我一直在尝试为项目编写c ++应用程序,但我遇到了这个问题。基本上是:
class OBSClass
{
public:
wstring ClassName;
uint8_t Credit;
uint8_t Level;
OBSClass() : ClassName(), Credit(), Level() {}
OBSClass(wstring name, uint8_t credit, uint8_t hyear)
: ClassName(name), Credit(credit), Level(hyear)
{}
};
在其他文件中:
vector<OBSClass> AllClasses;
...
AllClasses.push_back(OBSClass(L"Bilişim Sistemleri Mühendisliğine Giriş", 3, 1));
AllClasses.push_back(OBSClass(L"İş Sağlığı ve Güvenliği", 3, 1));
AllClasses.push_back(OBSClass(L"Türk Dili 1", 2, 1));
... (rest omitted, some of entries have non-ASCII characters like 'ş' and 'İ')
我有一个函数基本上输出AllClasses
中的所有内容,问题是wcout没有按照需要输出。
void PrintClasses()
{
for (size_t i = 0; i < AllClasses.size(); i++)
{
wcout << "Class: " << AllClasses[i].ClassName << "\n";
}
}
输出是'Class:Bili',没有别的。程序甚至不会尝试输出其他条目而只是挂起。我在使用G ++ 6.3.0的Windows上。我没有使用Windows的cmd,我使用mingw的bash,所以编码不会有问题(或者不是吗?)。有什么建议吗?
编辑:源代码编码也不是问题,只需检查它是UTF8,默认为VSCode
编辑:还要检查以查明字符串文字是否存在问题。
wstring test;
wcin >> test;
wcout << test;
输入一些非ASCII字符,如'ö'和'ş',它完美无缺。宽字符串文字有什么问题?
编辑:你走了
#include <iostream>
#include <string>
#include <vector>
using namespace std;
vector<wstring> testvec;
int main()
{
testvec.push_back(L"Bilişim Sistemleri Mühendisliğine Giriş");
testvec.push_back(L"ıiÖöUuÜü");
testvec.push_back(L"☺☻♥♦♣♠•◘○");
for (size_t i = 0; i < testvec.size(); i++)
wcout << testvec[i] << "\n";
return 0;
}
使用G ++编译: g ++ file.cc -O3
此代码仅输出'Bili'。它必须与g ++搞砸二进制编码(?),因为用wcin
输入值然后用wcout
输出它们不会产生任何问题。
答案 0 :(得分:1)
以下代码适用于我,在MSYS2 Bash和Windows CMD中使用MinGW-w64 7.3.0;并且源编码为UTF-8:
#include <iostream>
#include <locale>
#include <string>
#include <codecvt>
int main()
{
std::ios_base::sync_with_stdio(false);
std::locale utf8( std::locale(), new std::codecvt_utf8_utf16<wchar_t> );
std::wcout.imbue(utf8);
std::wstring w(L"Bilişim Sistemleri Mühendisliğine Giriş");
std::wcout << w << '\n';
}
说明:
wcout
以将输出转换为UTF-8。这是向后兼容性的默认设置,但Windows 10 1803确实添加了一个选项以将其设置为UTF-8 (ref)。imbue
codecvt_utf8_utf16
实现此目标;但是你还需要禁用sync_with_stdio
,否则流甚至不会使用facet,它只是推迟到有类似问题的stdout
。
为了写入其他文件,我发现相同的技术可以编写UTF-8。要编写UTF-16文件,您需要为wofstream
填充UTF-16方面see example here,并手动编写BOM。
评论:由于这些问题,许多人只是完全避免尝试完全使用广泛的iostream。
您可以使用窄流编写UTF-8文件;如果您在内部使用wstring
,则在代码中进行函数调用以将wstring
转换为UTF-8;你当然可以在内部使用UTF-8。
当然,您也可以使用窄流编写UTF-16文件,而不是使用operator<<
中的wstring
。
答案 1 :(得分:0)
如果您至少具有Windows 10 1903(2019年5月),并且至少具有 Windows Terminal 0.3.2142(2019年8月)。然后设置Unicode:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage]
"OEMCP"="65001"
,然后重新启动。之后,您可以使用以下代码:
#include <iostream>
int main() {
std::string a[] = {
"Bilişim Sistemleri Mühendisliğine Giriş",
"Türk Dili 1",
"İş Sağlığı ve Güvenliği",
"ıiÖöUuÜü",
"☺☻♥♦♣♠•◘○"
};
for (auto s: a) {
std::cout << s << std::endl;
}
}