将 UTF-16 转换为 UTF-8

2024-03-27

我目前使用 VC++ 2008 MFC。由于 PostgreSQL 不支持 UTF-16(Windows 使用的 Unicode 编码),我需要在存储之前将字符串从 UTF-16 转换为 UTF-8。

这是我的代码片段。

// demo.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "demo.h"
#include "Utils.h"
#include <iostream>

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// The one and only application object

CWinApp theApp;

using namespace std;

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
    int nRetCode = 0;

    // initialize MFC and print and error on failure
    if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
    {
        // TODO: change error code to suit your needs
        _tprintf(_T("Fatal Error: MFC initialization failed\n"));
        nRetCode = 1;
    }
    else
    {
        // TODO: code your application's behavior here.
    }

    CString utf16 = _T("Hello");
    std::cout << utf16.GetLength() << std::endl;
    CStringA utf8 = UTF8Util::ConvertUTF16ToUTF8(utf16);
    std::cout << utf8.GetLength() << std::endl;
    getchar();
    return nRetCode;
}

以及转换函数。

namespace UTF8Util
{
//----------------------------------------------------------------------------
// FUNCTION: ConvertUTF8ToUTF16
// DESC: Converts Unicode UTF-8 text to Unicode UTF-16 (Windows default).
//----------------------------------------------------------------------------
CStringW ConvertUTF8ToUTF16( __in const CHAR * pszTextUTF8 )
{
    //
    // Special case of NULL or empty input string
    //
    if ( (pszTextUTF8 == NULL) || (*pszTextUTF8 == '\0') )
    {
        // Return empty string
        return L"";
    }

    //
    // Consider CHAR's count corresponding to total input string length,
    // including end-of-string (\0) character
    //
    const size_t cchUTF8Max = INT_MAX - 1;
    size_t cchUTF8;
    HRESULT hr = ::StringCchLengthA( pszTextUTF8, cchUTF8Max, &cchUTF8 );

    if ( FAILED( hr ) )
    {
        AtlThrow( hr );
    }

    // Consider also terminating \0
    ++cchUTF8;

    // Convert to 'int' for use with MultiByteToWideChar API
    int cbUTF8 = static_cast<int>( cchUTF8 );

    //
    // Get size of destination UTF-16 buffer, in WCHAR's
    //
    int cchUTF16 = ::MultiByteToWideChar(
        CP_UTF8,                // convert from UTF-8
        MB_ERR_INVALID_CHARS,   // error on invalid chars
        pszTextUTF8,            // source UTF-8 string
        cbUTF8,                 // total length of source UTF-8 string,
                                // in CHAR's (= bytes), including end-of-string \0
        NULL,                   // unused - no conversion done in this step
        0                       // request size of destination buffer, in WCHAR's
        );

    ATLASSERT( cchUTF16 != 0 );

    if ( cchUTF16 == 0 )
    {
        AtlThrowLastWin32();
    }

    //
    // Allocate destination buffer to store UTF-16 string
    //
    CStringW strUTF16;
    WCHAR * pszUTF16 = strUTF16.GetBuffer( cchUTF16 );

    //
    // Do the conversion from UTF-8 to UTF-16
    //

    int result = ::MultiByteToWideChar(
        CP_UTF8,                // convert from UTF-8
        MB_ERR_INVALID_CHARS,   // error on invalid chars
        pszTextUTF8,            // source UTF-8 string
        cbUTF8,                 // total length of source UTF-8 string,
                                // in CHAR's (= bytes), including end-of-string \0
        pszUTF16,               // destination buffer
        cchUTF16                // size of destination buffer, in WCHAR's
        );

    ATLASSERT( result != 0 );

    if ( result == 0 )
    {
        AtlThrowLastWin32();
    }

    // Release internal CString buffer
    strUTF16.ReleaseBuffer();

    // Return resulting UTF16 string
    return strUTF16;
}

//----------------------------------------------------------------------------
// FUNCTION: ConvertUTF16ToUTF8
// DESC: Converts Unicode UTF-16 (Windows default) text to Unicode UTF-8.
//----------------------------------------------------------------------------
CStringA ConvertUTF16ToUTF8( __in const WCHAR * pszTextUTF16 )
{
    //
    // Special case of NULL or empty input string
    //
    if ( (pszTextUTF16 == NULL) || (*pszTextUTF16 == L'\0') )
    {
        // Return empty string
        return "";
    }

    //
    // Consider WCHAR's count corresponding to total input string length,
    // including end-of-string (L'\0') character.
    //
    const size_t cchUTF16Max = INT_MAX - 1;
    size_t cchUTF16;
    HRESULT hr = ::StringCchLengthW( pszTextUTF16, cchUTF16Max, &cchUTF16 );

    if ( FAILED( hr ) )
    {
        AtlThrow( hr );
    }

    // Consider also terminating \0
    ++cchUTF16;

    //
    // WC_ERR_INVALID_CHARS flag is set to fail if invalid input character
    // is encountered.
    // This flag is supported on Windows Vista and later.
    // Don't use it on Windows XP and previous.
    //

#if (WINVER >= 0x0600)
    DWORD dwConversionFlags = WC_ERR_INVALID_CHARS;
#else
    DWORD dwConversionFlags = 0;
#endif

    //
    // Get size of destination UTF-8 buffer, in CHAR's (= bytes)
    //
    int cbUTF8 = ::WideCharToMultiByte(
        CP_UTF8,                // convert to UTF-8
        dwConversionFlags,      // specify conversion behavior
        pszTextUTF16,           // source UTF-16 string
        static_cast<int>( cchUTF16 ),   // total source string length, in WCHAR's,
                                        // including end-of-string \0
        NULL,                   // unused - no conversion required in this step
        0,                      // request buffer size
        NULL, NULL              // unused
        );

    ATLASSERT( cbUTF8 != 0 );

    if ( cbUTF8 == 0 )
    {
        AtlThrowLastWin32();
    }

    //
    // Allocate destination buffer for UTF-8 string
    //
    CStringA strUTF8;
    int cchUTF8 = cbUTF8; // sizeof(CHAR) = 1 byte
    CHAR * pszUTF8 = strUTF8.GetBuffer( cchUTF8 );

    //
    // Do the conversion from UTF-16 to UTF-8
    //
    int result = ::WideCharToMultiByte(
        CP_UTF8,                // convert to UTF-8
        dwConversionFlags,      // specify conversion behavior
        pszTextUTF16,           // source UTF-16 string
        static_cast<int>( cchUTF16 ),   // total source string length, in WCHAR's,
                                        // including end-of-string \0
        pszUTF8,                // destination buffer
        cbUTF8,                 // destination buffer size, in bytes
        NULL, NULL              // unused
        ); 

    ATLASSERT( result != 0 );

    if ( result == 0 )
    {
        AtlThrowLastWin32();
    }

    // Release internal CString buffer
    strUTF8.ReleaseBuffer();

    // Return resulting UTF-8 string
    return strUTF8;
}

} // namespace UTF8Util

但是,在运行时,我收到异常

ATLASSERT( cbUTF8 != 0 );

尝试获取目标 UTF-8 缓冲区的大小时

  1. 我错过了什么?
  2. 如果我使用中文字符进行测试,如何验证生成的 UTF-8 字符串是否正确?

您还可以使用ATL 字符串转换宏 http://msdn.microsoft.com/en-us/library/87zae4a3.aspx- 从 UTF-16 转换为 UTF-8 使用CW2A并通过CP_UTF8作为代码页,例如:

CW2A utf8(buffer, CP_UTF8);
const char* data = utf8.m_psz;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 UTF-16 转换为 UTF-8 的相关文章

随机推荐

  • 间歇性地从 LinkedIn API 收到 999 请求被拒绝。原因代码1,2,1指的是什么

    在过去的两天里 两个不同的 LinkedIn 应用程序 开始间歇性地收到 999 请求被拒绝的错误 除此之外 我收到 reason code 1 2 1 作为标题 具体来说 这是从 oAuth 过程的第三步 与https www linke
  • R randomForest子集无法摆脱因子水平[重复]

    这个问题在这里已经有答案了 可能的重复 删除 R 中子集数据框中的因子级别 https stackoverflow com questions 1195826 dropping factor levels in a subsetted da
  • 计算 Google Sheets 脚本中的粗体单元格数量

    所以 说实话 我并不是一个编码员 但我已经设法通过计算单元格背景颜色来摸索 但努力让它适用于计算字体为粗体的单元格 我在下面详细介绍了我的函数 其中仅计算了 6 个具有粗体字体样式的单元格 但有 13 个具有粗体字体样式的单元格 funct
  • 相对时间序列

    我正在寻找一种标准化的方法来按相对时间排列数据 应用程序包括会计数据 例如 FY1 FY2 等 和经济数据 例如使用 1 年 2 年 3 年等的利率期限结构 我希望能够比较当前的一组时间序列数据和代表类似情况或历史规范的几个历史时间序列集
  • 立即处理至 App Store 后下架

    我的应用程序之前已下架 更新获得批准后 我在 10 分钟内收到了 3 封有关状态的电子邮件 1 处理至App Store 2 准备出售 3 停止销售 在 准备销售 状态之后 状态立即更改为 已从销售中删除 我联系了苹果公司 她说一旦应用程序
  • JavaScript XMLHttpRequest“网络错误”

    一般来说 我在 javascript 和 Web 开发方面缺乏经验 我正在从事的项目是一般公司培训计划的一部分 我们被指示使用 Google Chrome 作为主要测试浏览器 本质上 我正在编写一个将在公司内部网外部的客户端上运行的应用程序
  • 使用 Spark Web 框架时如何使用原生 Servlet Filter?

    我正在玩Spark http sparkjava com Java Web 框架 而不是 Apache Spark 我发现定义路由和过滤器非常好且容易 但是我希望将本机 servlet 过滤器应用于我的路由 但似乎找不到方法来做到这一点 更
  • 警告:preg_replace():未知修饰符“g”

    我遇到这个正则表达式错误 strTmp preg replace lt CharacterStyleRange gt n gim strTmp Error Warning preg replace 未知修饰符 g in Why g是隐含的p
  • 用于面部识别和标记的 Delphi 组件

    是否有任何好的组件 免费或商业 可用于 Delphi 我使用 Delphi 2009 使我能够轻松实现面部检测和标记照片 即图形 图像 中的面部 我需要做一些类似于 Google Picasa 网络相册可以做的事情 但是是在我的应用程序中进
  • 如何用Java实现子集和问题

    有谁知道如何通过这个伪代码在Java中实现子集和问题 w an array of positive integers sorted in non decreasing order W the target sum value include
  • 自动 AWS DynamoDB 到 S3 导出失败,并显示“role/DataPipelineDefaultRole 无效”

    严格按照以下说明进行操作这一页 http docs aws amazon com amazondynamodb latest developerguide DataPipelineExportImport Exporting html我正在
  • Angular:更改输入事件的值

    我有文本区域 我尝试将值的宽度限制为 10 个符号 我正在尝试削减价值input事件
  • 如何在我的 Webpack sass-loader 配置中指定包含 SCSS 的资源根?

    假设我有类似的东西 test scss exclude node modules loaders style loader css loader sass loader 在我的 webpack 配置中 我有一个app 包含我所有 SCSS
  • 选择 Qt 写入文本文件的自定义行结尾

    在 Qt 中写入文本文件时 使用 QFile 和 QTextStream 任何 n or endl自动转换为正确的平台特定行结尾 例如 r n对于 Windows 我想让用户选择使用哪个文件结尾 有没有办法在不使用二进制文件模式的情况下设置
  • 从 Byte[] 显示图像的最简单方法是什么?

    我有一个包含黑白图像的结构 public class Img public int height public int width public byte matrix 矩阵中包含的值为0或255 使用 C WPF 在组件中显示此图像的最佳
  • 并行位置

    并行性新手 正在学习使用 C 进行 HPX 的入门知识 我正在查看将打印的特定 hello word 示例hello world在每个位置的每个操作系统线程上 一些输出如下所示 hello world from OS thread 1 on
  • 列出子项 API 未提供驱动器/文件夹的所有子项

    我在获取用户 OneDrive 的文件 文件夹时遇到以下问题 击中时 https graph microsoft com v1 0 users https graph microsoft com v1 0 users 用户 ID 驱动器 我
  • GPU训练时Tensorflow 2.5退出代码-1073740791

    在 GPU 上训练 Tensorflow 模型时 调用 model fit 退出并带有代码 1073740791 0xC0000409 立即地 Epoch 1 500 2021 10 16 20 13 42 154951 I tensorf
  • 为 Visual Studio 2010 设置 OpenCV-2.3

    我正在尝试将 opencv 2 3 与 Visual Studio 2010 Express 一起使用 我的代码来自示例 include stdafx h include
  • 将 UTF-16 转换为 UTF-8

    我目前使用 VC 2008 MFC 由于 PostgreSQL 不支持 UTF 16 Windows 使用的 Unicode 编码 我需要在存储之前将字符串从 UTF 16 转换为 UTF 8 这是我的代码片段 demo cpp Defin