前段时间,写了一个小程序,涉及到很多的文件输入操作,几乎每一个文件格式都要写一个函数进行读取操作,一个是非常麻烦,另外就是非常容易出错。再加上这些数据中有中文字符的输入,在我前面的一篇文章里也说了,c++里处理中文字符非常麻烦(其实都麻烦),前面一篇是专门讲将wstring 转为string的文章,哈哈跑题了。
还有一个大问题是STL库的fstream 还有iostream 这些类在处理字符的时候显得那么笨拙,甚至ifstream,ofstream不支持中文的路径,让我实在忙活了一阵,于是每个函数都是用c实现的,加入了很多字符判断语句。 对于Local=“C”情况下,对unicode的判断需要以 *pch & 0x80 来判断,然后前移两个char * 的指针位再进行判断。这样一来,编写这样的函数实在是一个费力而且容易出错的事。
这些函数写多了,也归纳出了一些规律,于是就有了这个类的设计:
以下是设计概要:
1.过滤评论,空行等格式;
2.数据之间默认以space字符隔开,也可以定制隔离字符;
3.是否添入标签标识
4.对每行的控制还是全文控制
设计概要中3提到的标签表示是对于配置文件中经常有[tag],[group] 这样的标识,以明确指定配置的范围。由于暂时我的应用里没有用到,所以没有加入。另外,由于可以更好的控制输入的内容,选择的以每行的读取进行控制。下面是这个file_reader类的实现:
#include
<
string
>
#include < vector >
#include < string .h >
using namespace std;
class file_reader
... {
public:
file_reader(FILE *fp,const string & skip = ",",const string & comm="#/")
:_fp(fp),_skip(skip),_comment(comm)...{};
int getFromLine(vector<string> & vec)const;
private:
FILE * _fp;
string _skip;
string _comment;
} ;
int file_reader::getFromLine(vector < string > & vec) const
... {
int num=0;
char line[1024];
if(feof(_fp))
...{
return -1;
}
if(!feof(_fp) && fgets(line,1024,_fp))
...{
size_t len=strlen(line);
if(feof(_fp) && len<2)
...{
return -1;
}
if(len>1)
...{
if(line[len-1]==' ')
line[len-1]=0;
char * p,*v;
bool getword;
p=line;
while(*p)
...{
while(*p && (*p & 0x80)==0 &&(NULL!=strchr(_skip.c_str(),*p) ||isspace(*p))) p++;
if(*p==0) break;
if((*p & 0x80)==0 && NULL!=strchr(_comment.c_str(),*p))
...{
return num;
}
v=p;
getword=false;
while (*p)
...{
while(*p && (*p & 0x80)) p+=2;
while(*p && (*p & 0x80)==0 && !isspace(*p) && NULL==strchr(_skip.c_str(),*p)) p++;
if(*p && (*p & 0x80)==0 && (NULL!=strchr(_skip.c_str(),*p)|| isspace(*p)))
...{
getword=true;
*p++=0;
break;
}
}
if(*p==0 || getword)
...{
num++;
vec.push_back(string(v));
}
}
if(*p==0)
return num;
}
}
return num;
}
#include < vector >
#include < string .h >
using namespace std;
class file_reader
... {
public:
file_reader(FILE *fp,const string & skip = ",",const string & comm="#/")
:_fp(fp),_skip(skip),_comment(comm)...{};
int getFromLine(vector<string> & vec)const;
private:
FILE * _fp;
string _skip;
string _comment;
} ;
int file_reader::getFromLine(vector < string > & vec) const
... {
int num=0;
char line[1024];
if(feof(_fp))
...{
return -1;
}
if(!feof(_fp) && fgets(line,1024,_fp))
...{
size_t len=strlen(line);
if(feof(_fp) && len<2)
...{
return -1;
}
if(len>1)
...{
if(line[len-1]==' ')
line[len-1]=0;
char * p,*v;
bool getword;
p=line;
while(*p)
...{
while(*p && (*p & 0x80)==0 &&(NULL!=strchr(_skip.c_str(),*p) ||isspace(*p))) p++;
if(*p==0) break;
if((*p & 0x80)==0 && NULL!=strchr(_comment.c_str(),*p))
...{
return num;
}
v=p;
getword=false;
while (*p)
...{
while(*p && (*p & 0x80)) p+=2;
while(*p && (*p & 0x80)==0 && !isspace(*p) && NULL==strchr(_skip.c_str(),*p)) p++;
if(*p && (*p & 0x80)==0 && (NULL!=strchr(_skip.c_str(),*p)|| isspace(*p)))
...{
getword=true;
*p++=0;
break;
}
}
if(*p==0 || getword)
...{
num++;
vec.push_back(string(v));
}
}
if(*p==0)
return num;
}
}
return num;
}
void
readfile(
const
file_reader
&
fr)
... {
int num;
vector<string> vec;
while((num=fr.getFromLine(vec))!=-1)
...{
if(num==0)continue;
copy(vec.begin(),vec.end(),ostream_iterator<string>(cout," "));
vec.clear();
cout<<endl;
}
}
int main( int argc, char * argv[])
... {
string path="c:/test.txt";
FILE * fp = fopen(path.c_str(),"r");
if(fp)
...{
readfile(file_reader(fp));
rewind(fp);
readfile(file_reader(fp,",=","[#/")); //=号分割用于读取ini或者conf文件
fclose(fp);
}
return 0;
}
... {
int num;
vector<string> vec;
while((num=fr.getFromLine(vec))!=-1)
...{
if(num==0)continue;
copy(vec.begin(),vec.end(),ostream_iterator<string>(cout," "));
vec.clear();
cout<<endl;
}
}
int main( int argc, char * argv[])
... {
string path="c:/test.txt";
FILE * fp = fopen(path.c_str(),"r");
if(fp)
...{
readfile(file_reader(fp));
rewind(fp);
readfile(file_reader(fp,",=","[#/")); //=号分割用于读取ini或者conf文件
fclose(fp);
}
return 0;
}