getline() 读取 UTF-8 表情符号字符时到达文件末尾

问题描述 投票:0回答:1

我正在编写一个处理大型分隔文件的 C++ 程序。

我有一个 UTF-8 csv 文件,其中包含一行带有 (emoji?) 字符 🌟 的行。它看起来像这样:

123,"james","piotrj🌟","1996-01-28"

当我在这一行调用

getline()
时,它会读取表情符号,然后停止。所以从
getline()
得到的字符串是
123,"james","piotrj
。我不确定为什么会发生这种情况。如果我不得不猜测,我使用的区域设置不正确,并且这个表情符号(或其一部分)被解读为
EOF

我想按原样读取这一行,进行一些字符串操作,然后将其写入另一个文件。

我这里有一些示例代码:

locale loc("en_US.UTF8");
wifstream inFile;
inFile.imbue(loc);
inFile.open("MyFile.csv");
if(inFile.is_open()){
  wstring str;
  if (getline(inFile, str)) {
    wcout << str << endl;
  }
  if (getline(inFile, str)) {
    wcout << str << endl;
  }
  inFile.close();
}

此代码的输出是:

123,"james","piotrj
。第二个 if 语句主体不执行,因为第二个
getline()
没有抓取任何内容。

为了尝试一些事情,我将语言环境更改为:

locale loc = locale();

区域设置的名称是“C”,这将获取整行。该程序的输出是:

123,"james","piotrj🌟","1996-01-28"
。这是朝着正确方向迈出的一步,但如果没有正确的区域设置,wstring 将无法正确存储它。在我的程序中,我做了一些单独的字符检查,看看该字符串是否可以用 ANSI 表示,因此我真的希望 wstring 将该表情符号作为一个字符。

c++ locale emoji getline wstring
1个回答
0
投票

我想说一下我对

getline()
iostream
的个人看法。我希望它可以防止您和其他人犯错误并在生产代码中使用它。在使用 C++ 30 多年后,我得出的结论是,与 C 的严格规则相比,iostream 是为 C++ 中的任何操作符分配任何操作的可能性的鲜明证明。这是一个很好的例子,可以放入本书的第一页:

cout<<"Hello, world\n";

它仍然是 C++ 语言,但它 1) 非常慢,2) 它不会抛出异常,并且需要在每个 << or >> 之后进行错误检查,程序员通常不会这样做,因为所有示例都有很多 << in one line without any error checks. I would add 3) no detail documentations, because no-one interested to make detailed documentation for these classes, they are really joke classes only for demonstration purposes.

我的建议 - 如果您需要使用 IO,请使用 C stdio,它并没有过时,它由 C 程序员使用并支持,并且非常可预测。如果您需要 UTF8 和任何语言支持,请使用 ICU 库:它并不简单,但它涵盖了该领域所需的所有内容。

© www.soinside.com 2019 - 2024. All rights reserved.