-2

这是关于文本输入文件中的 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("%d\n", list_map0.size());
    file.close();
}

unicode 符号从 csv 文件中读取并解析为 unicode 符号和关联的字符串。最初我虽然代码中有一个错误,但在这篇文章中,审查发现它很好,我关注了如何处理字符的问题。

测试是cout << wow << endl;

4

3 回答 3

1

您显示的字符都是 Windows 代码页 1252 中的所有字符,这些字符在 ISO-8859 1 编码中不存在。这两种编码相似,因此经常混淆。

如果输入是 CP1252 并且您正在读取它,就好像它是 ISO-8859 1 一样,那么这些字符将被读取为控制字符,并且不会像正常的可见字符那样表现。


您可能做错了很多事情来导致这种情况,但是您必须发布更多详细信息才能确定是哪一个。更完整的答案需要了解您如何读取数据、如何在内部转换和存储数据、如何测试读取的数据以及输入数据和/或编码。


您显示的代码在读取数据时不会进行任何转换,用于打印数据的注释掉的代码是相同的;没有转换。这意味着要打印数据,您只是依赖输入数据来正确运行程序的平台。这意味着,例如,如果您在 Windows 的控制台中运行程序,那么您的输入文件需要使用控制台的代码页*进行编码。

要解决问题,您可以;确保输入文件与您运行程序的特定控制台所需的编码匹配;或者指定输入编码,读取时转换为已知的内部编码,然后打印时转换为控制台编码。

* 如果不是,例如如果控制台是 cp437 而文件是 cp1252,那么您列出的字符将改为显示为:É æ Æ ô ö ò û ù ÿ Ö Ü ¢ £ ¥ ₧ ƒ á í ó ú ñ Ñ ª º ¿ ⌐ ¬ ½ ¼ ¡ « »

于 2013-01-14T19:09:25.427 回答
0

您的问题陈述没有详细说明 g++ 的平台,但从您的标签看来,您正在 linux 上编译相同的代码。

Windows 和 linux 都启用了 unicode。因此,如果您在 windows/vs-2008 中的代码具有 wstring 类,那么您必须在 linux/g++ 上将其更改回字符串。如果您在 linux 中使用 wstring,它将不会以相同的方式工作。

于 2013-01-14T18:54:49.060 回答
0

C++ 代码中的 Unicode 处理并不简单,它依赖于实现(您已经看到输出在 VS2008 和 g++ 之间发生了变化)。此外,Unicode 可以通过不同的字符编码(如 UTF-8 和 UTF-16)来实现。

本页有一篇启发性的文章。它讨论了基于 STL 的软件的 Unicode 转换。对于文本 i/o,主要武器是codecvt,这是一个库函数,可用于在不同字符编码系统之间转换字符串。

于 2013-01-14T18:59:58.740 回答