配置文件和简单格式的文件读取类的设计和实现

    前段时间,写了一个小程序,涉及到很多的文件输入操作,几乎每一个文件格式都要写一个函数进行读取操作,一个是非常麻烦,另外就是非常容易出错。再加上这些数据中有中文字符的输入,在我前面的一篇文章里也说了,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(*&& (*& 0x80)==0 &&(NULL!=strchr(_skip.c_str(),*p) ||isspace(*p))) p++;
                
if(*p==0break;
                
if((*& 0x80)==0 && NULL!=strchr(_comment.c_str(),*p))
                
{
                    
return num;
                }

                v
=p;
                getword
=false;
                
while (*p)
                
{
                    
while(*&& (*& 0x80)) p+=2;
                    
while(*&& (*& 0x80)==0 && !isspace(*p) && NULL==strchr(_skip.c_str(),*p)) p++;
                    
if(*&& (*& 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;
}
现在我读取文件输入和conf文件都用这个类实现,非常方便,对于类成员函数返回的读入个数值可以根据实际应用进行过滤,也可以达到排错的作用。希望大家喜欢这个小工具:-)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值