getline问题和“奇怪的人物”

时间:2011-08-12 12:48:27

标签: c++ wstring

我有一个奇怪的问题, 我用

wifstream a("a.txt");
wstring line;
while (a.good()) //!a.eof()  not helping
{
     getline (a,line);
      //...
     wcout<<line<<endl;

}

它适用于像这样的txt文件 http://www.speedyshare.com/files/29833132/a.txt (对不起链接,但它只有80个字节,所以它应该不是一个问题,如果我在SO新行上的c / p丢失) 但是当我添加例如水(从http://en.wikipedia.org/wiki/UTF-16/UCS-2#Examples)到任何加载停止的行的行时。我错误的认为getline将wstring作为一个输入和wifstream,因为其他人可以咀嚼任何txt输入... 有没有办法读取文件中的每一行,即使它包含时髦的字符?

3 个答案:

答案 0 :(得分:7)

不太令人满意的答案是,您需要使用能够理解所讨论的特定字符编码的语言环境来灌输输入流。如果您不知道要选择哪个区域设置,则可以使用空区域设置。

例如(未经测试):

std::wifstream a("a.txt");
std::locale loc("");
a.imbue(loc);

不幸的是,没有标准的方法来确定给定平台可用的区域设置,更不用说根据字符编码选择一个。

上面的代码将区域设置选择放在用户手中,如果他们将其设置为合理的东西(例如en_AU.UTF-8),那么它可能都是Just Work。

如果不这样做,您可能需要使用第三方库,例如iconvICU

这也是blog entry的相关信息(为自我推销道歉)。

答案 1 :(得分:3)

问题在于您对全局函数getline (a,line)的调用。这需要std::string。使用std::wistream::getline方法代替getline函数。

答案 2 :(得分:3)

C ++ fstreams将I / O删除到他们的filebuf。 filebuf始终从磁盘读取“原始字节”,然后使用流语言环境的codecvt facet将这些原始字节转换为“内部编码”。

wfstreambasic_fstream<wchar_t>因此有一个basic_filebuf<wchar_t>,它使用区域设置的codecvt<wchar_t, char>将从磁盘读取的字节转换为wchar_t s。如果您读取UCS-2编码文件,则必须使用“知道”外部编码为UCS-2的编解码器执行转换。因此,您需要具有此类codecvt的语言环境(例如,请参阅this SO question

默认情况下,流的区域设置是流构造中的全局区域设置。要使用特定的区域设置,请在流上添加imbue() - d。