这是一个关于文本输入文件中的unicode字符的问题。这个讨论很接近,但并不是答案。使用VS2008编译并在Windows上执行,这些字符在读取时被识别(可能表示为不同的符号,但读取)-使用g++编译并在linux上执行时,它们显示为空白。
‚ ƒ „ … † ‡ ˆ ‰ Š ‹ Œ Ž ‘ ’ “ ” • – — ˜ ™ š › œ ž Ÿ
其余的Unicode符号似乎可以正常工作,我没有检查它们,但发现这组不能工作。
问题:(1)为什么?(2)有解决办法吗?
void Lexicon::buildMapFromFile(string filename ) //map
{
ifstream file;
file.open(filename.c_str(), ifstream::binary);
string wow, mem, key;
unsigned int x = 0;
while(true) {
getline(file, wow);
cout << wow << endl;
if (file.fail()) break; //boilerplate check for error
while (x < wow.length() ) {
if (wow[x] == ',') { //look for csv deliniator
key = mem;
mem.clear();
x++; //step over ','
} else
mem += wow[x++];
}
//cout << mem << " code " << key << " is " << (key[0] - '€') << " from €" << endl;
cout << "enter 1 to continue: ";
while (true) {
int choice = GetInteger();
if (choice == 1) break;
}
list_map0[key] = mem; //char to string
list_map1[mem] = key; //string to char
mem.clear(); //reset memory
x = 0;//reset index
}
//printf("%dn", list_map0.size());
file.close();
}
从csv文件中读取unicode符号,并解析其unicode符号和相关字符串。最初我认为代码中有一个错误,但在这篇文章的审查中发现它是好的,我遵循这个问题,如何处理字符。
测试是cout << wow << endl;
您显示的字符都是来自Windows代码页1252的字符,这些字符在ISO-8859 1编码中不存在。这两种编码是相似的,所以经常被混淆。
如果输入是CP1252,你读它就好像它是ISO-8859 1,那么这些字符将被作为控制字符读取,而不会像正常的可见字符那样表现。
有很多可能的事情你可能做错了导致这个,但你必须发布更多的细节,以确定是哪一个。一个更完整的答案需要知道如何读取数据,如何在内部转换和存储数据,如何测试读取数据,以及输入数据和/或编码。
您显示的代码在读取数据时不做任何转换,并且注释掉的代码打印数据是相同的;没有转换。这意味着打印您所依赖的输入数据对于运行程序的平台是正确的。这意味着,例如,如果您在Windows的控制台中运行程序,那么您的输入文件需要使用控制台的代码页*.
进行编码。要解决这个问题,您可以;确保输入文件与运行程序的特定控制台所需的编码匹配;或者指定输入编码,在读取时转换为已知的内部编码,然后在打印时转换为控制台编码。
*,如果不是,例如,如果控制台是cp437,文件是cp1252,那么您列出的字符将显示为:É æ Æ ô ö ò û ù¾Ö Ü¢£¥
您的问题说明没有详细说明g++的三个平台,但从您的标记来看,您似乎正在linux上编译相同的代码。
Windows和linux都启用unicode。所以,如果你的代码在windows/vs-2008中有wstring类,那么,你必须在linux/g++中将其更改回string。如果您在linux中使用wstring,它将不会以相同的方式工作。
c++代码中的Unicode处理并不简单,它取决于实现(您已经看到VS2008和c++之间的输出变化)。此外,Unicode可以通过不同的字符编码(如UTF-8和UTF-16)来实现。
本页有一篇启发性的文章。它讨论了基于stl的软件的Unicode转换。对于文本输入/输出,主要武器是codecvt,这是一个库函数,可用于在不同字符编码系统之间转换字符串。