代码之家  ›  专栏  ›  技术社区  ›  rubenvb

UTCPP和Win32范围的API

  •  2
  • rubenvb  · 技术社区  · 14 年前

    用小号的好/安全/可以吗 utfcpp 用于将我从宽窗口API(findfirstfilew等)获得的所有内容转换为使用utf16to8的有效utf8表示的库?

    我希望在内部使用utf8,但在获得正确的输出(通过wcout在另一个转换或plain cout之后)时遇到问题。当然,正常的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." );
        }
    }
    
    2 回复  |  直到 13 年前
        1
  •  7
  •   Hans Passant    14 年前

    win32 api已经有一个函数来执行此操作,widechartomultibyte(),codepage=cp_tf8。使您不必依赖其他库。

    通常不能将结果与wcout一起使用。它的输出到控制台,出于传统原因,它使用8位OEM编码。可以使用setconsolecp()更改代码页,65001是utf-8(cp_utf8)的代码页。

    下一个绊脚石是用于控制台的字体。你将不得不改变它,但要找到一个固定的字体,有一套完整的字形覆盖Unicode将是困难的。当您得到输出中的方形矩形时,您会发现字体有问题。问号是编码问题。

        2
  •  3
  •   Community Egal    7 年前

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

    在内部使用win32 api自带的宽字符,只在读取或写出需要它的数据(如xml文件或rest api)时才进行utf8转换,您的代码将更干净、更容易处理。

    您的问题也可能发生在将输出打印到控制台的位置,请参见: Output unicode strings in Windows console app

    最后,我还没有使用utfcpp库,但是使用win32进行utf8转换非常简单。 WideCharToMultiByte MultiByteToWideChar 具有 CP_UTF8 作为代码页。就我个人而言,我会进行一次性转换,并使用UTF16格式的文本,直到需要时输出或传输到UTF8格式为止。