C++ 如何读取包含汉字的UTF-8编码文件并在控制台上正确输出?

C++ 如何读取包含汉字的UTF-8编码文件并在控制台上正确输出?,c++,utf-8,readfile,chinese-locale,C++,Utf 8,Readfile,Chinese Locale,我正在写一个网络爬虫来获取一些中文网络文件。获取的文件以utf-8编码。我需要读取这些文件来进行一些解析,比如提取URL和汉字。但我发现,当我将文件读入std::string变量并将其输出到控制台时,汉字变成了垃圾字符。我将boost::regex应用到std::string变量中,可以提取除中文字符以外的所有URL 我如何解决这些问题 p.S.我的CPP文件默认编码为ANSI,操作系统为中文Win8 通常,使用w变体(wstring,wfstream,wcout),设置您的区域设置以符合要求,

我正在写一个网络爬虫来获取一些中文网络文件。获取的文件以utf-8编码。我需要读取这些文件来进行一些解析,比如提取URL和汉字。但我发现,当我将文件读入std::string变量并将其输出到控制台时,汉字变成了垃圾字符。我将boost::regex应用到std::string变量中,可以提取除中文字符以外的所有URL

我如何解决这些问题


p.S.我的CPP文件默认编码为ANSI,操作系统为中文Win8

通常,使用
w
变体(
wstring
wfstream
wcout
),设置您的区域设置以符合要求,在字符串文本的前面挂一个
L
locale::global(locale(“”)
设置为匹配环境默认值,然后在每个未根据该默认值运行的流上,例如,
wcout.imbue(locale(“China_China.936”))
设置终端的区域设置。这已经足够做我想做的了,希望它对你也能起作用

#include <iostream>
#include <locale>
using namespace std;
int main() {
  locale::global(locale(""));
  wstring word;
  while (wcin >>word)
    wcout<<word<<'\n';
  wcout<<L"好運n";
}
#包括
#包括
使用名称空间std;
int main(){
区域设置::全局(区域设置(“”);
字词;
while(wcin>>word)

wcout如果需要正确显示字符,可以从GNU使用libiconv。 如果只需要处理URL,std::string就可以了。 问题是windows控制台的代码页,而不是字符串本身。 使用区域设置取决于操作系统和stdc++lib的实现,所以我不鼓励使用

window的MultiByteToWideChar可能会有所帮助,但您需要检查MS关于这些函数如何对字符串执行转换的规范。

此代码可能会有所帮助(它是用VC++2010编译的)。我用一个包含非拉丁字符的UTF-8文件测试了它,它似乎可以工作,但我不知道它是否可以与中文字符一起工作。有关详细信息,请查看以下链接:和

#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;//很抱歉!
无效读取所有行(常量wchar\t*filename)
{
wifstream-wifs;
wstring-txtline;
int c=0;
打开(文件名);
如果(!wifs.is_open())
{

wcerr听起来好像您需要将“代码页”从UTF-8更改为您的控制台用于汉字的任何代码页。调用MultiByteToWideChar从UTF-8更改为Unicode,然后调用WideCharToMultiByte从Unicode更改为本地代码页。很可能是控制台的错误。尝试将
更改为文件。如果结果是这样的话要使UTF-8具有中文字符,那么您的程序工作正常,这是一个Windows问题。(当然,您可能仍需要更改程序以在Windows环境下工作,但您将知道谁有错。)@aib是的,当我将std::string变量重定向到另一个文件中时,内容仍然是有效的带有中文字符的UTF-8。我的控制台的代码页是
“936(ANSI/OEM-简体中文 GBK)”
。您的解决方案是在其他平台上工作还是仅在Windows下的VC上工作?
#include <iostream>
#include <fstream>
#include <string>
#include <locale>
#include <codecvt>
#include <fcntl.h>
#include <io.h>

using namespace std;    // Sorry for this!

void read_all_lines(const wchar_t *filename)
{
    wifstream wifs;
    wstring txtline;
    int c = 0;

    wifs.open(filename);
    if(!wifs.is_open())
    {
        wcerr << L"Unable to open file" << endl;
        return;
    }
    // We are going to read an UTF-8 file
    wifs.imbue(locale(wifs.getloc(), new codecvt_utf8<wchar_t, 0x10ffff, consume_header>()));
    while(getline(wifs, txtline))
        wcout << ++c << L'\t' << txtline << L'\n';
    wcout << endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
    // Console output will be UTF-16 characters
    _setmode(_fileno(stdout), _O_U16TEXT);
    if(argc < 2)
    {
        wcerr << L"Filename expected!" << endl;
        return 1;
    }
    read_all_lines(argv[1]);
    return 0;
}