我正在尝试在c ++中实现Text类,该类加载文本文件(.txt),搜索该文件中的每个字符并存储所有单词和所有定界符(在这种情况下,定界符将是所有一个字符)在两个各自的向量(#include <vector>
)中。由于文本文件main包含特殊字符,因此我使用setlocale(LC_ALL, "pt_BR.UTF-8")
设置了程序的语言环境。
随着下面代码的执行(作为类文本的构造函数),我注意到在构造ifstream类并且代码进入while
循环之后,我进入了char c
已使用arch.get(c)
存储,其中包含一个无法识别的角色(这个坏男孩在这里:▒)。
在这种情况下,c
是特殊字符,如果显示字母(由string d
标识),它将保存在字符串(isalpha(c)
)上并在下一个循环中保存。在文件上,它将string d
存储在各自的分隔符矢量上。相同的逻辑适用于字母,因为它们先保存在string p
上,然后再保存在单词vector(英语中的 words = palavras )中。我最困惑的部分是当我打印string d
并检查其值时,文件中识别出的特殊字符会正确显示。
为什么将特殊字符插入string
才能识别特殊字符?为什么arch.get(c)
函数返回无法识别的字符?
以下代码是类Text
的构造函数。用于测试的打印带有注释以供指示。
Text::Text( string na ) {
// Inicialization of variables
total_size = 0;
word_first_flag = false;
namearch = na;
string p = "";
string d = "";
vector<string>::iterator it_delim;
it_palavras = palavras.begin();
it_delim = delim.begin();
setlocale(LC_ALL, "pt_BR.UTF-8");
ifstream arch(namearch);
char c;
while(arch.get(c)) {
if(total_size > 10000)
break;
cout << c << endl; // Prints ▒
switch (isalpha(c)) { // does not recognize special characters
case 0:
if(p == "") {
d = d + c;
cout << "-" << d << "-"<< endl; // Prints correct char
}
else {
Palavra paux;
paux = p;
palavras.push_back(paux);
p = "";
d = d + c;
}
break;
default:
if(total_size == 0) word_first_flag = true;
if(d == "") {
p = p + c;
}
else {
delim.push_back(d);
cout << "-" << d << "-" << " Inserted!" << endl << endl; // Also prints correct char
d = "";
p = p + c;
}
break;
}
++total_size;
}
}
if(d != "")
delim.push_back(d);
it_palavras = palavras.begin();
arch.close();
}
根据locale
类的文档,对于特殊字符,一切都应正常工作。但是事实并非如此。我也尝试过在字符串中插入c,但是它只是保存了错误的字符。根据{{3}}
wstrings
和wchat_t
的所有类型,但是语言环境设置显然已经做到了
在C ++中,语言环境由语言环境类的对象表示。每 这些语言环境对象中包含使用 一系列与文化相关的功能。
我正在Cygwin的gcc
6.4.0版本上进行编译。我也知道我可以使用gdb
进行调试,但是在此阶段并没有太大帮助。
答案 0 :(得分:0)
因此,通过@Igor Tandetnik的非常有用的见解以及对这些类型的数据进行的一些测试,我已经更改了原始代码,以便它可以正确地从存档中提取特殊字符。
Text::Text( string na ) {
// Inicialization of variables
total_size = 0;
word_first_flag = false;
namearch = na;
wstring p = L"";
wstring d = L"";
vector<wstring>::iterator it_delim;
it_palavras = palavras.begin();
it_delim = delim.begin();
setlocale(LC_ALL, "pt_BR.UTF-8");
wifstream arch(namearch);
wchar_t c;
while(arch.get(c)) {
if(total_size > 10000)
break;
wcout << c << endl;
switch (iswalpha(c)) {
case 0:
if(p == L"") {
d = d + c;
wcout << "-" << d << "-"<< endl;
}
else {
Palavra paux;
paux = p;
palavras.push_back(paux);
p = L"";
d = d + c;
}
break;
default:
if(total_size == 0) word_first_flag = true;
if(d == L"") {
p = p + c;
}
else {
delim.push_back(d);
wcout << "-" << d << "-" << " Inserted!" << endl << endl;
d = L"";
p = p + c;
}
break;
}
++total_size;
}
}
if(d != L"")
delim.push_back(d);
it_palavras = palavras.begin();
arch.close();
}
简而言之,对代码的调整是:
将所有char
,string
和iostream更改为其多字节格式(例如:wchar_t
,wstring
和wcout
) ;
在每个字符或字符串(L
或L''
)前添加L""
进行多字节转换。