【问题标题】:How do I read a text file having Unicode codes?如何读取具有 Unicode 代码的文本文件?
【发布时间】:2013-08-23 06:49:06
【问题描述】:

我使用以下代码初始化一个字符串。

  std::string unicode8String = "\u00C1 M\u00F3ti S\u00F3l";

使用cout 打印,输出为Á Móti Sól

但是当我使用 ifstream 从文本文件中读取相同的字符串,将其存储在 std::string 中并打印出来时,输出为 \u00C1 M\u00F3ti S\u00F3l

我的文件内容是\u00C1 M\u00F3ti S\u00F3l,我想将其打印为Á Móti Sól。有没有办法做到这一点?

【问题讨论】:

  • 我确定以前有人问过这个问题。你搜索了吗?
  • 您的问题中没有 UTF 代码。如果要将六个字符串 \u00C1 转换为值为 0xC1 的字符,则必须编写代码来解析字符串。没有快速的答案。但是,由于您对自己在做什么感到困惑,我认为您可能真的想做其他事情。很难说是什么。
  • 是的,我搜索了但找不到解决方案。
  • @john 我想要做的是:示例:我拥有的文本文件:\u00C1 M\u00F3ti S\u00F3l 我希望我的程序能够读取并打印Á Móti Sól。这个有什么功能吗?
  • @Anubha 不,但你可以自己写,看我的回答。

标签: c++ file ubuntu file-io utf


【解决方案1】:

在我的脑海中(完全未经测试)

std::string convert_string(const std::string& in)
{
    std::string out;
    for (size_t i = 0; i < in.size(); )
    {
        if (i + 5 < in.size() && in[i] == '\\' && in[i+1] == 'u' && 
            in[i+2] == '0' && in[i+3] == '0' && 
            isxdigit(in[i+4]) && isxdigit(in[i+5]))
        {
            out += (unsigned char)16*in[i+4] + (unsigned char)in[i+5];
            i += 6;
        }
        else
        {
            out += in[i];
            ++i;
        }
    }
    return out;
}

但这不适用于任何高于 255 的 unicode 值(例如 \u1234),因为您的字符串存储 8 位字符的基本问题,而 Unicode 字符最多可以有 20 位。

正如我所说的完全未经测试,但我相信你明白了。

【讨论】:

  • 所以我必须自己写一个函数?据我了解 \u00C1 是 Á,而 \u00F3 是 ó 等等......所以这是 Unicode 字符,所以没有任何预先存在的函数/库退出吗?
  • 你们两个需要决定那些 unicode 转义字符是否在字符串中。约翰是这么假设的,而你似乎不确定。
  • txt 文件包含 \u00C1 M\u00F3ti S\u00F3l,所以当我将它读入字符串时,字符串有“\u00C1 M\u00F3ti S\u00F3l”
  • @Anubha,回答这个问题,它会减少很多混乱。您的文件中的字符串“\u00C1”有多长,是六个字符还是一个字符?
  • 文件中有六个字符。
【解决方案2】:

您可以尝试使用“std::wcout”进行打印吗!

【讨论】:

    【解决方案3】:

    unicode 字符在文本文件中具有不同的表示形式(没有 \u)。

    用于评估

    int main()
    {
        // Write
        {
            std::string s = "\u00C1 M\u00F3ti S\u00F3l";
            std::ofstream out("/tmp/test.txt");
            out << s;
        }
        // Read Text
        {
            std::string s;
            std::ifstream in("/tmp/test.txt");
            std::getline(in, s);
            std::cout << "Result: " << s << std::endl;
        }
        // Read Binary
        {
            std::ifstream in("/tmp/test.txt");
            in.unsetf(std::ios_base::skipws);
            std::istream_iterator<unsigned char> first(in);
            std::istream_iterator<unsigned char> last;
            std::vector<unsigned char> v(first, last);
            std::cout << "Result: ";
            for(unsigned c: v) std::cout << std::hex << c << ' ';
            std::cout << std::endl;
        }
        return 0;
    }
    

    在带有 UTF8 的 Linux 上: 结果:Á Móti Sól 结果:c3 81 20 4d c3 b3 74 69 20 53 c3 b3 6c

    【讨论】:

    • 我的意思是该文件不是 UTF8 格式,该文件的字面意思是字符串“\u00C1 M\u00F3ti S\u00F3l”而不是Á Móti Sól。随着您的写入,文件开始包含Á Móti Sól。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-02
    • 1970-01-01
    • 2012-08-21
    • 1970-01-01
    • 2013-09-14
    相关资源
    最近更新 更多