C++中编码格式导致的中文乱码问题,JNI和C++交互场景下常见

一、背景介绍

        项目需要完成Java调用C++库实现对应功能,在实现时未考虑中文问题。在传递字符串参数时,如果字符串为全英文,则可以正常运行,在传递的字符串中存在中文时,发现参数值不符合预期,出现乱码。

二、原因分析

        从传递参数含中文时出现乱码可以知道问题出现在编码格式上,网上查阅相关资料,是不同编码格式下中文存储长度问题导致。针对分析的原因对字符进行字节长度适配。

三、解决方法

1、标准库中有对不同编码格式字符长度进行调整的函数,int WideCharToMultiByte( UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar);  相关参数说明如下:
  • UINT CodePage, 指定目标多字节编码的代码页标识符。常见的值包括 CP_ACP(系统默认的 ANSI 代码页)和 CP_UTF8(UTF-8 编码)等。
  •  DWORD dwFlags, 指定转换的行为选项。一般情况下,可以使用 0。
  •  LPCWSTR lpWideCharStr, 指向要进行转换的宽字符字符串的指针。
  •  int cchWideChar, 要进行转换的宽字符字符串的长度,以字符数(wchar_t 的个数)表示。
  •  LPSTR lpMultiByteStr, 指向用于接收转换结果的多字节字符缓冲区的指针。
  •  int cbMultiByte, 指定接收转换结果的多字节字符缓冲区的大小(以字节为单位)。
  •  LPCSTR lpDefaultChar, 指向一个字符的指针,在转换过程中,如果遇到无法映射为多字节字符的宽字符或无效序列,将使用此字符作为替代。
  •  LPBOOL lpUsedDefaultChar 指向一个布尔值的指针,用于指示是否使用了默认字符替代。
 2、主要参数为需要转换的字符串字符串长度目标字符串目标字符串长度。详细的实现代码如下,入参为需要处理的字符串jcstr字符串长度strLen
char* stringUnicodeAdapte1(const jchar* jcstr, int strLen)
{
  // 计算有效的字符串长度
  int validLength = 0;
  for (int i = 0; i < strLen; ++i) {
      if (jcstr[i] != '\0') {
          ++validLength;
      } else {
          break;
      }
  }

  /**
   * 字符转换函数说明:函数的返回值是转换后的多字节字符的长度(以字节为单位),不包括终止空字符。
   * int WideCharToMultiByte(
   * UINT CodePage, 指定目标多字节编码的代码页标识符。常见的值包括 CP_ACP(系统默认的 ANSI 代码页)和 CP_UTF8(UTF-8 编码)等。
   * DWORD dwFlags, 指定转换的行为选项。一般情况下,可以使用 0。
   * LPCWSTR lpWideCharStr, 指向要进行转换的宽字符字符串的指针。
   * int cchWideChar, 要进行转换的宽字符字符串的长度,以字符数(wchar_t 的个数)表示。
   * LPSTR lpMultiByteStr, 指向用于接收转换结果的多字节字符缓冲区的指针。
   * int cbMultiByte, 指定接收转换结果的多字节字符缓冲区的大小(以字节为单位)。
   * LPCSTR lpDefaultChar, 指向一个字符的指针,在转换过程中,如果遇到无法映射为多字节字符的宽字符或无效序列,将使用此字符作为替代。
   * LPBOOL lpUsedDefaultChar 指向一个布尔值的指针,用于指示是否使用了默认字符替代。
   * );  
  */
  //计算转换后的字符个数
  int jCharCnt = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)jcstr, validLength, NULL, 0, NULL, NULL);
  char* adapteCharPtr(new char[jCharCnt]); // 使用智能指针管理内存
  int adapteStrLen = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)jcstr, validLength, adapteCharPtr, jCharCnt, NULL, NULL);
  adapteCharPtr[adapteStrLen] = 0;    //确保多字节字符字符串以空字符结尾,使其符合 C 风格字符串的约定。

  return adapteCharPtr;
}

以上方法为网上查阅资料和自己总结生成,有错误和不足之处请指正,谢谢!欢迎转发交流!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值