4

使用小型utfcpp库将我从广泛的 Windows API(FindFirstFileW 等)返回的所有内容转换为使用 utf16to8 的有效 UTF8 表示是否很好/安全/可能?

我想在内部使用 UTF8,但无法获得正确的输出(在另一次转换或普通 cout 后通过 wcout)。正常的 ASCII 字符当然可以,但是 ñä 会搞砸。

还是有更简单的选择?

谢谢!

更新:感谢 Hans(下),我现在可以通过 Windows API 轻松进行 UTF8<->UTF16 转换。两种方式转换有效,但来自 UTF16 字符串的 UTF8 有一些额外的字符,以后可能会给我带来一些麻烦......)。出于纯粹的友好,我会在这里分享它:)):

// UTF16 -> UTF8 conversion
std::string toUTF8( const std::wstring &input )
{
    // get length
    int length = WideCharToMultiByte( CP_UTF8, NULL,
                                      input.c_str(), input.size(),
                                      NULL, 0,
                                      NULL, NULL );
    if( !(length > 0) )
        return std::string();
    else
    {
        std::string result;
        result.resize( length );

        if( WideCharToMultiByte( CP_UTF8, NULL,
                                 input.c_str(), input.size(),
                                 &result[0], result.size(),
                                 NULL, NULL ) > 0 )
            return result;
        else
            throw std::runtime_error( "Failure to execute toUTF8: conversion failed." );
    }
}
// UTF8 -> UTF16 conversion
std::wstring toUTF16( const std::string &input )
{
    // get length
    int length = MultiByteToWideChar( CP_UTF8, NULL,
                                      input.c_str(), input.size(),
                                      NULL, 0 );
    if( !(length > 0) )
        return std::wstring();
    else
    {
        std::wstring result;
        result.resize( length );

        if( MultiByteToWideChar(CP_UTF8, NULL,
                                input.c_str(), input.size(),
                                &result[0], result.size()) > 0 )
            return result;
        else
            throw std::runtime_error( "Failure to execute toUTF16: conversion failed." );
    }
}
4

2 回答 2

7

Win32 API 已经有一个函数可以做到这一点,WideCharToMultiByte() with CodePage = CP_UTF8。使您不必依赖另一个库。

您通常不能将结果与 wcout 一起使用。它的输出进入控制台,出于遗留原因,它使用 8 位 OEM 编码。您可以使用 SetConsoleCP() 更改代码页,65001 是 UTF-8 (CP_UTF8) 的代码页。

您的下一个绊脚石将是用于控制台的字体。您必须对其进行更改,但要找到一种固定间距且具有涵盖 Unicode 的全套字形的字体将很困难。当您在输出中获得方形矩形时,您会看到字体问题。问号是编码问题。

于 2010-07-25T15:54:52.963 回答
3

为什么要在内部使用 UTF8?您是否正在处理如此多的文本,以至于使用 UTF16 会产生不合理的内存需求?即使是这种情况,您还是最好还是使用宽字符,并以其他方式处理内存问题(使用磁盘缓存、更好的算法或数据结构)。

在内部使用 Win32 API 原生的宽字符时,您的代码将更加简洁和容易处理,并且仅在读取或写入需要它的数据(例如 XML 文件或 REST API)时进行 UTF8 转换。

您的问题也可能发生在您将输出打印到控制台的位置,请参阅:在 Windows 控制台应用程序中输出 unicode 字符串

最后,我没有使用 utfcpp 库,但是使用 Win32 和作为代码页执行 UTF8 转换相当WideCharToMultiByte简单。就我个人而言,我会进行一次转换并使用 UTF16 格式的文本,直到需要时以 UTF8 格式输出或传输它。MultiByteToWideCharCP_UTF8

于 2010-07-25T15:52:44.707 回答