我遇到了一个问题,无法在互联网上find答案。 尽pipe我发现了很多类似的问题,但是没有任何答案适用于我。 所以我的部分代码是:
wstring books[50]; wstring authors[50]; wstring genres[50]; wstring takenBy[50]; wstring additional; bool taken[50]; _setmode(_fileno(stdout), _O_U8TEXT); wifstream fd("bookList.txt"); i = 0; while (!fd.eof()) { getline(fd, books[i]); getline(fd, authors[i]); getline(fd, genres[i]); getline(fd, takenBy[i]); fd >> taken[i]; getline(fd, additional); i++; }
我需要的是用C ++读取以UTF-8编码的文本文件。 但是,当我读取文件时,这些宽string会被改变,当我打印它们时,输出文本是完全不同的。 input: ąčę输出: ÄÄÄ如何避免并正确阅读文本? 我正在使用Visual Studio 2015,C ++,Windows 10。
UTF-8 (可能)不在宽字符串中。 了解有关UTF-8的信息 。 UTF-8使用8位字节 (有时几个 字节 )来编码Unicode字符。 所以在C ++中,一个unicode字符从1到6个字节的序列(即char
-s)被解析。
你需要一些UTF-8解析器,而C11或C ++ 11标准不提供任何解析器。 所以你需要一些外部库。 看看libunistring (这是一个简单的C UTF-8解析库)或其他东西( Qt , POCO , Glib , ICU ,…)。 你可以决定解析UTF-8并将其转换为UTF-32 (使用u32string
-s和char32_t
)并向后转换,或者你最好决定在UTF-8内部工作(使用std::string
和char
)
因此,你将解析和打印序列的char
-s(使用UTF-8编码),你的程序将使用普通的std::string
-s和普通的char
-s(不是std::wstring
或wchar_t
),但处理UTF-8序列 …
Boost.Spirit很容易:
#define BOOST_SPIRIT_UNICODE #include <boost/spirit/include/qi.hpp> #include <iostream> #include <string> using namespace boost::spirit; int main() { std::string in("ąčę"); std::string out; qi::parse(in.begin(), in.end(), +unicode::char_, out); std::cout << out << std::endl; }
以下示例读取一系列元组(book,authors,takenBy):
#define BOOST_SPIRIT_UNICODE #include <boost/spirit/include/qi.hpp> #include <boost/fusion/adapted/std_tuple.hpp> #include <iostream> #include <string> #include <tuple> #include <vector> using namespace boost::spirit; int main() { std::string in("Book_1\nAuthors_1\nTakenBy_1\n"\ "Book ąčę\nAuthors_2\nTakenBy_2\n"); std::vector< std::tuple< std::string, /* book */ std::string, /* authors */ std::string /* takenBy */ > > out; auto ok = qi::parse(in.begin(), in.end(), *( +(unicode::char_ - qi::eol) >> qi::eol /* book */ >> +(unicode::char_ - qi::eol) >> qi::eol /* authors */ >> +(unicode::char_ - qi::eol) >> qi::eol /* takenBy */ ), out); if(ok) { for(auto& entry : out) { std::string book, authors, takenBy; std::tie(book, authors, takenBy) = entry; std::cout << "book: " << book << std::endl << "authors: " << authors << std::endl << "takenBy: " << takenBy << std::endl; } } }
这只是一个使用std::tuple
和一个未命名解析器的演示,它是qi::parse
的第三个参数。 您可以使用结构而不是元组来表示书籍,作者,流派等等。未命名的解析器可能被语法所取代,您可以将文件的内容读取到要传递给qi::parse
的字符串中。