c++ 字符串讀寫

這幾天一直在解決座位號重複問題,所以考慮到用文件讀寫來判斷字符串是否重複。


剛開始是使用固定的長度來寫入文件和替換字符串,但是考慮到代碼的複用性,後來還是修改了任意字符串的讀寫和替換,方便以後使用。


1:添加字符串到文件:

函數原型:bool AddSeatID(char *_setNum,int length);

函數實現:

bool CFileTest::AddSeatID(char *_setNum,int length)
{
	if (checkDuplicate(_setNum))
	{
		return false;
	}
	if (!openFile("ab+"))
	{
		printf("open file failed \n");
		return false;
	}
	char seatBuf[length+4];
	memset(seatBuf,0,length+4);
	memcpy(seatBuf,"[",1);
	memcpy(seatBuf+1,_setNum,length);
	memcpy(seatBuf+length+1,"]\r\n",3);
	fseek(m_fp,0L,SEEK_END);
	fwrite(seatBuf,length+4,1,m_fp);
	closeFile();
	m_seatIDList.push_back(_setNum);

	return true;
}
已追加方式寫入文件,其中有使用判斷字符串是否存在於文件中,如果有存在則返回false,不存在則寫入文件。其中設置m_seatIDList爲vector容器,將字符串保存到內存中


2:字符串重複判斷函數:

函數原型:bool checkDuplicate(char* _seatID);

函數實現:

bool CFileTest::checkDuplicate(char* _seatID)
{
	string seatID;
	if (m_seatIDList.empty())
	{
		return false;
	}
	vector<string>::iterator iter;
	vector<string>::iterator beginVec = m_seatIDList.begin();
	vector<string>::iterator endVec = m_seatIDList.end();

	for (iter = beginVec; iter!= endVec; iter++)
	{
 		if (!strcmp(iter->c_str(),_seatID))
		{
			return true;
		}
	}
	return false;
}
將需要判斷重複的字符串傳入,並將此字符串與文件中讀出的字符串進行比較


3:替換新舊字符串函數:

函數原型:bool changeSeatID(char* _oldSeat,int _oldLength,char* _newSeat,int _newLength);

函數實現:

bool CFileTest::changeSeatID(char* _oldSeat,int _oldLength,char* _newSeat,int _newLength)
{
	if (checkDuplicate(_newSeat))
	{
		return false;
	}
	if (replaceSeatID(_oldSeat,_oldLength,_newSeat,_newLength))
	{
		return true;
	}
	return false;

}
將新舊字符串以及相應的字符串長度傳入,如果文件中有存在與就字符串相同的字符串,就將新字符串傳入替換函數中進行替換


4:替換函數:

函數原型:bool replaceSeatID(char* _oldSeat,int _oldLength,char* _newSeat,int _newLength);

函數實現:

bool CFileTest::replaceSeatID(char* _oldSeat,int _oldLength,char* _newSeat,int _newLength)
{
	int oldoffset =0;
	int newoffset =0;
	char buf[128];
	if (!openFile("r+"))
	{
		printf("open file failed \n");
		return false;
	}
	while(getline(buf,128))
	{
		oldoffset = newoffset;
		newoffset = ftell(m_fp);
		int i = 0;
		char seatNumberTemp[20]={0};
		while(i < 128)
		{
			if(buf[i] == '\0' || buf[i] == '\n')
			{
				break;
			}
			if(buf[i] == '[')
			{
				int i_begin;
				i_begin = ++i;
				while(buf[i]!=']')
				{
					i++;
				}
				i--;
				memcpy(seatNumberTemp,buf+i_begin,i-i_begin+1);
				if (strcmp(seatNumberTemp,_oldSeat))
				{
					break;
				}
				else
				{
					memset(buf+i_begin,0,i-i_begin+4);
					fseek(m_fp,oldoffset+i_begin,SEEK_SET);
					fwrite(buf+i_begin,i-i_begin+4,1,m_fp);
					memcpy(buf+i_begin,_newSeat,_newLength);
					buf[i_begin+_newLength]=']';
					buf[i_begin+_newLength+1]='\r';
					buf[i_begin+_newLength+2]='\n';
					fseek(m_fp,oldoffset,SEEK_SET);

					fwrite(buf,i_begin+_newLength+2,1,m_fp);//此處不能修改爲3,不然短字符串
										//修改爲長字符串時,會導致下一行的字符串丟失"["
					closeFile();
					//update file mapping memory
					
					vector<string>::iterator iter;
					vector<string>::iterator beginVec = m_seatIDList.begin();
					vector<string>::iterator endVec = m_seatIDList.end();
					for (iter = beginVec; iter!= endVec; iter++)
					{
						if (!strcmp(iter->c_str(),_oldSeat))
						{
							break;
						}
					}
					m_seatIDList.erase(iter);
					m_seatIDList.push_back(_newSeat);
					return true;
				}
			}
			else
			{
				i++;
			}
		}//end of parse a line while

	}//end of while  file
	closeFile();
	AddSeatID(_newSeat,_newLength);
	//update file mapping memory
	return true;
}//end of func
將文件中每行字符串讀出,並去除[]內的字符串與舊字符串對比,如果相同就開始將就字符串替換成新的字符串,如果不相同,就以新字符串形式寫入文件中


5:整行讀入函數:

函數原型:bool getline(char* buf, unsigned int length);

函數實現:

bool CFileTest::getline(char* buf, unsigned int length)
{
	int len = 0;
	if(fgets(buf, length, m_fp) != NULL)
		return true;
	else
		return false;
}


6:初始化函數:

函數原型:bool init();

函數實現:

bool CFileTest::init()
{
	 return updataSeatList();
}

7:更新容器中字符串函數:

函數原型:bool updataSeatList();

函數實現:

bool CFileTest::updataSeatList()
{
	if (!openFile("ab+"))
	{
		return false;
	}
	if (!m_seatIDList.empty())
	{
		m_seatIDList.clear();
	}
	char buf[128];
	memset(buf, 0, 128);
	if (m_fp != NULL)
	{
		while(getline(buf,128))
		{
			string SeatID;
			int i = 0;
			while(i < 128)
			{
				if(buf[i] == '#' || buf[i] == '\0' || buf[i] == '\n')
				{
					break;
				}
				else if(buf[i] == ' ')
				{
					i++;
					continue;
				}
				else if(buf[i] == '[')
				{
					int i_begin;
					i_begin = ++i;
					while(buf[i]!=']'){
						i++;
					}
					SeatID.assign(buf+i_begin, i-i_begin);
					break;
				}
				else
				{
					i++;
				}
			}
			m_seatIDList.push_back(SeatID);

		}
	}
	closeFile();
	return true;
}

8:打開、關閉文件函數:

函數原型: bool openFile(char* mode);        void closeFile();

函數實現:

bool CFileTest::openFile(char* mode)
{
	closeFile();
	m_fp = fopen(SEATIDFILE,mode);
	if (m_fp == NULL)
	{
		return false;
	}
	return true;
}

void CFileTest::closeFile()
{
	if (m_fp!= NULL)
	{
		fclose(m_fp);
		m_fp = NULL;
	}
}
9:main函數:

#include "filetest.h"
int main()
{
	CFileTest filet;
	if (filet.checkDuplicate("cc003"))
	{
		filet.changeSeatID("cc003",5,"a04",3);

	}else{
		char * str = "cc032";
		int len = strlen(str);
		filet.AddSeatID(str,len);
		filet.AddSeatID("ccjkj8967",9);
		filet.AddSeatID("a01",3);
		filet.AddSeatID("a02",3);
		filet.AddSeatID("a03",3);
		filet.AddSeatID("bb01",4);
		filet.AddSeatID("bb02",4);
		filet.AddSeatID("bb03",4);
		filet.AddSeatID("cc001",5);
		filet.AddSeatID("cc002",5);
		filet.AddSeatID("cc003",5);
		filet.AddSeatID("ccjkj89",7);
	}
	return 0;
}

10:filetest.h文件:

#ifndef FILETEST_H 
#define FILETEST_H


#include <fstream>
#include <iostream>
#include <cstring>
#include <vector>  
#include <sstream> 
#include <stdbool.h>
using namespace std;

class CFileTest{

public:
	CFileTest();
	~CFileTest();
	bool init();
	bool checkDuplicate(char* _seatID);
	bool getline(char* buf, unsigned int length);
	bool updataSeatList();
	bool openFile(char* mode);
	void closeFile();
	bool replaceSeatID(char* _oldSeat,int _oldLength,char* _newSeat,int _newLength);
	bool AddSeatID(char *_setNum,int length);
	bool changeSeatID(char* _oldSeat,int _oldLength,char* _newSeat,int _newLength);
	FILE* m_fp;
	vector<string> m_seatIDList;


};
#endif



11:字符串寫入結果展示:

第一次寫入文件:                                                      第二次將[ccjkj8967]->[cc005]:                                    第三次將[cc0033]->[a04]:


                                                                                               


12:總結:

因爲最終的項目時在linux系統運行的,所以這部分代碼最終是在Ubuntu上運行調試的並能成功寫入與替換,在windows的vs2008上並沒有調試,可能會因爲頭文件的問題導致編譯不通過,添加相應的頭文件應該就可以了。因爲已經轉戰java快兩年了,c++部分也忘記的差不多了,代碼中可能存在不足,請大家見諒


13:demo下載地址:http://download.csdn.net/download/qq_27922603/9985024





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章