我正在尝试在我的c ++应用程序中使用立陶宛语,但每次尝试都是不成功的。
使用多字节字符集。我已经尝试了所有我想要的东西,我是c ++的新手。从来没有尝试用立陶宛语做某事。
尝试每setlocale(LC_ALL, "en_US.utf8"); setlocale(LC_ALL, "Lithuanian");
...
研究了2个小时,没有找到合适的例子,解决方案。
我确实有一个平均大小的项目,需要从数据库中进行立陶宛语翻译,而且它无法理解“ĄČĘĖĮŠŲŪąčęėįšųū”的大部分内容。
编译器 - “Visual studio 2013” 数据库 - sqlite3。
我无法使用简单的字符串(自己定义),甚至可以输出立陶宛语作为win32应用程序。
答案 0 :(得分:1)
在Windows中,使用宽字符串( 1 UTF-16编码,wchar_t
类型)进行内部文本处理,最好使用UTF-8进行外部文本文件和网络。
请注意,Visual C ++会将源文件中的窄文本文字转换为Windows ANSI,这是一种依赖于平台的通常是单字节编码(您可以通过GetACP
API函数检查哪一个),即Visual C ++具有特定于平台的Windows ANSI作为其窄C ++执行字符集。
但是请注意,对于仅限于非Windows平台的应用程序,即Unix-land,根据char
类型执行UTF-8中的所有操作都是切实可行的。
对于数据库通信,您可能需要在程序的内部文本表示中进行翻译。
这取决于数据库接口需要什么,这没有说明。
Windows中控制台输出的示例:
#include <iostream>
#include <fcntl.h>
#include <io.h>
auto main() -> int
{
_setmode( _fileno( stdout ), _O_WTEXT );
using namespace std;
wcout << L"ĄČĘĖĮŠŲŪąčęėįšųū" << endl;
}
要使用g ++进行默认编译,源代码编码必须为UTF-8。然后,为了使用Visual C ++生成正确的结果,源代码编码需要是带有BOM 的UTF-8 ,现代版本的g ++也很乐意接受它。否则,Visual C ++编译器将采用Windows ANSI编码并生成不正确的UTF-16字符串。
这并非巧合,这是Windows中 UTF-8 的默认含义,例如:在记事本编辑器中,即带有BOM的UTF-8。
但请注意,虽然在Windows中问题是主系统编译器需要用于UTF-8的BOM,但在Unix版本中,问题恰恰相反,许多旧工具可以& #39; t处理 BOM(例如,即使MinGW g ++ 4.9.1还没有完全达到速度:它有时包括BOM字节,然后错误解释,在错误消息中)。
1 )在其他平台上,宽字符文本可以用其他方式编码,例如使用UTF-32。实际上,Windows约定与C和C ++标准直接冲突,这些标准要求单个wchar_t
应该能够对扩展字符集中的任何字符进行编码。然而,这个要求是AFAIK,在Windows采用UTF-16之后施加,所以错误可能在于C和C ++标准化过程的政治,而不是另一个微软的主义。
答案 1 :(得分:0)
国际化的复杂性
有几个相关但不同的主题可能导致它们之间的不匹配,使得尝试和错误方法非常乏味:
类型:默认情况下,Windows iuses wchar_t
,但对于大多数API,您还有char
等效函数
字符集编码,它定义了如何理解存储在类型中的字符。例如unicode(UTF8,UTF16,UTF32),7位ascii,8位ansii。在windows中,默认情况下wchar_t
为UTF16,char
为ansi / windows
locale 在处理字符串时定义了字符集的假设等。这允许使用与isalpha(i, loc)
,islower(i, loc)
,ispunct(i, loc)
等语言无关的函数来查明给定字符是否为字母数字,小写字母或标点符号,例如用户文字成文字。 C ++提供了便携式功能。
输出代码页或字体。这假定font used使用代码内部使用的相同字符集显示字符。
源代码编码。例如,您的编辑器可以采用带有Windows 1252字符集的ansi编码。
最典型的错误
问题n°1是Win32控制台输出,因为控制台不能很好地支持unicode。但这不是你的问题。
不匹配的另一个原因是文本编辑器的编码。它可能不是unicode,但使用Windows代码页。在这种情况下,您键入“Č”,编辑器将其显示为此类,但编辑器可能会对立陶宛语使用windows 1257编码并在文件中存储0xC8。如果你随后用windows unicode函数显示这个文字,它会将0xC8解释为“latin E grave accent”并打印其他东西,因为“Č”的右unicode编码是0x010C!
我可能更糟糕:编译器可能有自己的关于使用的字符集编码的假设,并使用错误的假设将你的litteral转换为unicode(当我使用一些奇特的代码生成开关时,它发生在我身上)。
怎么办?
要弄清楚是什么,请继续消除:
TEXT("\u010C")
而不是TEXT("Č")
。这可以避免编辑器和编译器不匹配。 例如,一个非常微小的实验:
...
case WM_PAINT:
{
hdc = BeginPaint(hWnd, &ps);
auto hf = CreateFont(24, 0, 0, 0, 0, TRUE, 0, 0, 0, 0, 0, 0, 0, L"Times New Roman");
auto hfOld = SelectObject(hdc, hf); // if you comment this out, € and Č won't display
TextOut(hdc, 50, 50, L"Test with éç € \u010C special chars", 30);
SelectObject(hdc, hfOld);
DeleteObject(hf);
EndPaint(hWnd, &ps);
break;
}