这几天一直在解决座位号重复问题,所以考虑到用文件读写来判断字符串是否重复。
刚开始是使用固定的长度来写入文件和替换字符串,但是考虑到代码的复用性,后来还是修改了任意字符串的读写和替换,方便以后使用。
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将需要判断重复的字符串传入,并将此字符串与文件中读出的字符串进行比较::iterator iter; vector ::iterator beginVec = m_seatIDList.begin(); vector ::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将文件中每行字符串读出,并去除[]内的字符串与旧字符串对比,如果相同就开始将就字符串替换成新的字符串,如果不相同,就以新字符串形式写入文件中::iterator iter; vector ::iterator beginVec = m_seatIDList.begin(); vector ::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; }
函数原型:bool init();
函数实现:
bool CFileTest::init() { return updataSeatList(); }
函数原型: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; }
函数原型: 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; }
#ifndef FILETEST_H #define FILETEST_H #include#include #include #include #include #include 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 m_seatIDList; }; #endif
11:字符串写入结果展示:
第一次写入文件: 第二次将[ccjkj8967]->[cc005]: 第三次将[cc0033]->[a04]:
12:总结:
因为最终的项目时在linux系统运行的,所以这部分代码最终是在Ubuntu上运行调试的并能成功写入与替换,在windows的vs2008上并没有调试,可能会因为头文件的问题导致编译不通过,添加相应的头文件应该就可以了。因为已经转战java快两年了,c++部分也忘记的差不多了,代码中可能存在不足,请大家见谅
13:demo下载地址:http://download.csdn.net/download/qq_27922603/9981263