请大家帮我看一下这个控制台程序,这个程序主要是做字符串的识别插入的,例如说:
查找特征字符,以str1“。~”开始,而后在“。~”之后查找str2“123456789”(带圈数字)字串任意字符的第一次出现,如果找到这样的匹配,则在找到str1的位置之前插入str1_Insert,在找到str2的位置之前插入str2_Insert,因为涉及到中文字符,因此用的是wstring类型(string类型按字节查找会匹配出错)!
程序完成了,通过编译,而且查找插入也是正确的,可是有一个问题总感觉很奇怪,例如我用测试文本进行测试(该文本有1000行),可最终总是只能输入一部分,对容器size发现文本没有全部读入容器之中,这是什么原因呢?是内存不够还是wstring引起的问题呢(之前用string实现就能完全输出只是查找插入出错)!
下面是代码:#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <locale> 
using namespace std;//打开文件
wifstream& open_file(wifstream &in,const string &file)
{
in.close();
in.clear();
in.open(file.c_str());
cout << "i opened the file!" << endl;
return in;
}//读入容器
vector<wstring>& set_vec(wifstream &in,vector<wstring> &vec)
{
wstring temp;
while(getline(in,temp)){
vec.push_back(temp);
}
cout << "i finished the set_vec!" << endl;
return vec;
}//字符串完全匹配查找插入
wstring& deal_vec(wstring &str,const wstring &str1_to_find,const wstring &str2_to_find,
const wstring &str1_to_In,const wstring &str2_to_In)
{
wstring::size_type pos_begin = 0;
do{
wstring::size_type pos1 = str.find(str1_to_find,pos_begin);
if(pos1 != wstring::npos){
str.insert(pos1,str1_to_In);
wstring::size_type pos2 = str.find(str2_to_find,pos1+str1_to_In.length());
if(pos2 != wstring::npos){
str.insert(pos2,str2_to_In);
pos_begin = pos2+str2_to_In.length();
}
}
else
pos_begin = wstring::npos;
}while(pos_begin < str.length());
cout << "i finished the str insert!" << endl;
return str;
}//首子字串完全匹配,次子字串任意匹配
wstring& deal_first_vec(wstring &str,const wstring &str1_to_find,const wstring &str2_to_find,
const wstring &str1_to_In,const wstring &str2_to_In)
{
wstring::size_type pos_begin = 0;
do{
wstring::size_type pos1 = str.find(str1_to_find,pos_begin);
if(pos1 != wstring::npos){
wstring::size_type pos2 = str.find_first_of(str2_to_find,pos1);
if(pos2 != wstring::npos){
str.insert(pos2,str2_to_In);
str.insert(pos1+1,str1_to_In);
//cout<<str1_to_In.length()<<str2_to_In.length();
pos_begin = pos2+str1_to_In.length()+str2_to_In.length();
}
else
pos_begin = wstring::npos;
}
else
pos_begin = wstring::npos;
}while(pos_begin < str.length());
cout << "i finished the str insert!" << endl;
return str;
}//写入文件
void write_file(wofstream &out,const string &file,const wstring &toWrite)
{
out.open(file.c_str(),wofstream::out|wofstream::app);
out << toWrite << endl;
out.close();
out.clear();
// cout << "write the file for one line!" << endl;
}int main()
{
locale lang("chs"); 
string read_file,ofile;
const wstring str1_find(L"△");
const wstring str2_find(L"/");//"/"全角,0xA3AF
const wstring str1_Insert(L"<JP>");
const wstring str2_Insert(L"</JP>");
const wstring str3_find(L"。~");
const wstring str4_find(L"①②③④⑤⑥⑦⑧⑨");//全角带圈数字序号
vector<wstring> vec;
wifstream fin;
wofstream fout;
fin.imbue(lang);//本地化
fout.imbue(lang);
cout << "请输入要处理的文件" << endl;
cin >> read_file;
cout << "请输入输出文件名" << endl;
cin >> ofile;
if(open_file(fin,read_file))
{
set_vec(fin,vec);
cout << vec.size() << endl;
for(vector<wstring>::iterator iter = vec.begin(); iter != vec.end(); ++iter)
{
deal_first_vec(*iter,str3_find,str4_find,str1_Insert,str2_Insert);
write_file(fout,ofile,*iter);
}
}
else
cout<< "cannot open the file! "<<endl;
return 0;
}

解决方案 »

  1.   

    http://topic.csdn.net/t/20021005/18/1073995.html
      

  2.   

    测试文本是GBK的,Unicode读不了,测试文本的格式大概是这样的:
    测试1 测试 文本。~测试1①测试1注释。~测试2②测试2注释。~测试3③测试3注释。~测试4④测试1注释。
    测试2 测试 文本。~测试1①测试1注释。~测试2②测试2注释。~测试3③测试3注释。~测试4④测试2注释。
    测试3 测试 文本。~测试1①测试1注释。~测试2②测试2注释。~测试3③测试3注释。~测试4④测试3注释。
    测试4 测试 文本。~测试1①测试1注释。~测试2②测试2注释。~测试3③测试3注释。~测试4④测试4注释。
    ...
    测试1000...
    结束
      

  3.   

    wstring是以2个字节为基本单位的,你取它的size取到的大体上是字节数/2,它只能存储UTF-16的字符串,GBK不能用它存储,要用string。
      

  4.   

    GBK编码,如果用string的话,str.find_first_of(str2_to_find,pos1),如果str2_to_find是一个包含中文的字符串,如“测试”0xB2E2 0xCAD4,处理上述的函数时,只要str中含有0xB2 0xE2这样的字节,就会被认为是匹配的,会出现匹配错误!
    另外,我刚用vs2008编译了上述代码,发现没有出现我所描述的问题,可以正常运行并且得出正确的匹配结果,测试文本5.5万行、GBK编码的,怎么回事呢?
      

  5.   

    GBK编码是MBC不是UNICODE。VC6.0默认不是UNICODE,vs2008默认是UNICODE。不过你的测试文本可不是UNICODE的!
      

  6.   

    string.find找不到很正常,因为它本来就不支持中文的解析,它只是存储你的字符串,相当于一个二进制数组。要想实现你的需求(对GBK字符串的搜索),必须自己想办法或者去找开源代码。