J. *_*awa 5 c++ windows utf-8 visual-c++
我正在尝试从C ++应用程序的控制台读取UTF-8编码的波兰语字符。我确定控制台使用此代码页(已签入属性)。我已经尝试过的:
在主要功能的开头,我有以下几行:
setlocale(LC_ALL, "PL_pl.UTF-8");
SetConsoleOutputCP(CP_UTF8);
SetConsoleCP(CP_UTF8);
Run Code Online (Sandbox Code Playgroud)
我将非常感谢您的帮助。
这是我用于 UTF-8 支持的技巧。结果是多字节字符串,然后可以在其他地方使用:
#include <cstdio>
#include <windows.h>
#define MAX_INPUT_LENGTH 255
int main()
{
SetConsoleOutputCP(CP_UTF8);
SetConsoleCP(CP_UTF8);
wchar_t wstr[MAX_INPUT_LENGTH];
char mb_str[MAX_INPUT_LENGTH * 3 + 1];
unsigned long read;
void *con = GetStdHandle(STD_INPUT_HANDLE);
ReadConsole(con, wstr, MAX_INPUT_LENGTH, &read, NULL);
int size = WideCharToMultiByte(CP_UTF8, 0, wstr, read, mb_str, sizeof(mb_str), NULL, NULL);
mb_str[size] = 0;
std::printf("ENTERED: %s\n", mb_str);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
应该是这样的:
PS 非常感谢 Remy Lebeau 指出一些缺陷!
尽管您已经接受了答案,但这里有一个更便携的版本,它更接近标准库。不幸的是,这是我发现许多广泛使用的实现不支持标准中的内容的一个领域。例如,应该有一种标准的方式来打印多字节字符串(理论上这可能像 shift-JIS 那样不寻常,但实际上在每个现代操作系统上都是 UTF-8),但它实际上并不能移植。微软的运行时库在这方面特别差,但我也发现了 libc++ 中的错误。
/* Boilerplate feature-test macros: */
#if _WIN32 || _WIN64
# define _WIN32_WINNT 0x0A00 // _WIN32_WINNT_WIN10
# define NTDDI_VERSION 0x0A000002 // NTDDI_WIN10_RS1
# include <sdkddkver.h>
#else
# define _XOPEN_SOURCE 700
# define _POSIX_C_SOURCE 200809L
#endif
#include <iostream>
#include <locale>
#include <locale.h>
#include <stdlib.h>
#include <string>
#ifndef MS_STDLIB_BUGS // Allow overriding the autodetection.
/* The Microsoft C and C++ runtime libraries that ship with Visual Studio, as
* of 2017, have a bug that neither stdio, iostreams or wide iostreams can
* handle Unicode input or output. Windows needs some non-standard magic to
* work around that. This includes programs compiled with MinGW and Clang
* for the win32 and win64 targets.
*
* NOTE TO USERS OF TDM-GCC: This code is known to break on tdm-gcc 4.9.2. As
* a workaround, "-D MS_STDLIB_BUGS=0" will at least get it to compile, but
* Unicode output will still not work.
*/
# if ( _MSC_VER || __MINGW32__ || __MSVCRT__ )
/* This code is being compiled either on MS Visual C++, or MinGW, or
* clang++ in compatibility mode for either, or is being linked to the
* msvcrt (Microsoft Visual C RunTime) library.
*/
# define MS_STDLIB_BUGS 1
# else
# define MS_STDLIB_BUGS 0
# endif
#endif
#if MS_STDLIB_BUGS
# include <io.h>
# include <fcntl.h>
#endif
using std::endl;
using std::istream;
using std::wcin;
using std::wcout;
void init_locale(void)
// Does magic so that wcout can work.
{
#if MS_STDLIB_BUGS
// Windows needs a little non-standard magic.
constexpr char cp_utf16le[] = ".1200";
setlocale( LC_ALL, cp_utf16le );
_setmode( _fileno(stdout), _O_WTEXT );
_setmode( _fileno(stdin), _O_WTEXT );
#else
// The correct locale name may vary by OS, e.g., "en_US.utf8".
constexpr char locale_name[] = "";
setlocale( LC_ALL, locale_name );
std::locale::global(std::locale(locale_name));
wcout.imbue(std::locale());
wcin.imbue(std::locale());
#endif
}
int main(void)
{
init_locale();
static constexpr size_t bufsize = 1024;
std::wstring input;
input.reserve(bufsize);
while ( wcin >> input )
wcout << input << endl;
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
无论初始语言环境或代码页如何,这都会从控制台读取宽字符输入。如果您的意思是输入将是 UTF-8 编码中的字节(例如来自 UTF-8 编码的重定向文件),而不是控制台输入,那么完成此操作的标准方法应该是从UTF-8 到wchar_tin<codecvt>和<locale>,但实际上 Windows 不支持 Unicode 语言环境,因此您必须读取字节,然后手动转换它们。一种更标准的方法是mbstowcs(). 我有一些旧代码可以为 STL 迭代器进行转换,但标准库中也有转换函数。无论如何,您可能需要这样做,例如,如果您需要以 UTF-8 格式保存或传输。
还有一些谁将会推荐使用基于某种形式的UTF-16对像Windows的API内部甚至当,转换成只有当你进行API调用另一个编码存储您的所有字符串UTF-8。我强烈建议您尽可能在外部使用 UTF-8,但我不会走那么远。但是请注意,将字符串存储为 UTF-8 将为您节省大量内存,尤其是在wchar_tUCS-32 的系统上。你会比我更清楚这通常会为波兰语文本节省多少字节。
| 归档时间: |
|
| 查看次数: |
1905 次 |
| 最近记录: |