将 gbk编码的字符串 转换成 utf-8 后,存储到注册表出现数据丢失的问题

test_lockxxx 2019-03-22 04:13:28
因为我的程序使用的 gbk 编码,另一个程序使用的是 utf-8 编码,两者需要通过注册表交互,所以我在对注册表操作的时候,需要将字符由gbk转为utf-8,存储到注册表,等待另一个使用utf-8编码的程序来读取这个注册表项。


将一个【含有中文路径】的字符串由 gbk 编码转换成 utf-8 编码后,存储到注册表后,有时出现数据丢失现象。

【含有中文路径】举例:

D:\新2


代码调试:

gbk:'d:\新2'
0x64 0x3a 0x5c 0xd0 0xc2 0x32

utf-8:'d:\鏂?'
utf-8-len:7
0x64 0x3a 0x5c 0xe6 0x96 0xb0 0x32

读注册表内容:
read:'d:\鏂?'
read:len:7
0x64 0x3a 0x5c 0xe6 0x96 0x3f 0x0


存储后,在程序中直接读取注册表项,发现数据不对了,从 0x3f 开头。

如何解决数据丢失这个问题?
...全文
291 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
test_lockxxx 2019-04-02
  • 打赏
  • 举报
回复
这也许是一个无解的问题。 结贴,感谢大家回复。
test_lockxxx 2019-03-26
  • 打赏
  • 举报
回复
@zgl7903 你的程序文件内部使用的是 utf-8 编码吧,我的程序文件内部使用的是 gbk 编码,使用你的代码后,测试结果和我之前是一样的。 我写的程序源代码使用的是 gbk 编码, 但需要在程序中将 gbk 编码的 "新2" 转换成 utf-8 编码后,存储到注册表的 REG_SZ 。 "d:\新2" 转换成 utf-8 后了字节: 0x64 0x3a 0x5c 0xe6 0x96 0xb0 0x32 但不知为什么,存储到注册表(REG_SZ)后,在我的程序中再读取注册表项时,读取到的字节变成了: 0x64 0x3a 0x5c 0xe6 0x96 0x3f 0x0 为什么数据变了?
zgl7903 2019-03-25
  • 打赏
  • 举报
回复


CHAR srcGbk[] =
{
0x64, 0x3a, 0x5c, 0xd0, 0xc2, 0x32, 0x00,
};

HKEY hPrimKey = HKEY_CURRENT_USER;
LPCWSTR szSubKey = L"Software\\myTest";
LPCWSTR szValueName = L"TestValule";

const int CP_GBK = 936;

//写入测试
{
//GBK-->UNICODE
int iWLen = MultiByteToWideChar(CP_GBK, 0, srcGbk, -1, NULL, 0);
WCHAR *wChString = new WCHAR[iWLen + 1];
MultiByteToWideChar(CP_GBK, 0, srcGbk, -1, wChString, iWLen);
wChString[iWLen] = 0;

//UNICODE-->UTF8
int iUtf8Len = WideCharToMultiByte(CP_UTF8, 0, wChString, -1, NULL, 0, NULL, NULL);
CHAR *szUtf8String = new CHAR[iUtf8Len + 1];
WideCharToMultiByte(CP_UTF8, 0, wChString, -1, szUtf8String, iUtf8Len, NULL, NULL);
szUtf8String[iUtf8Len] = 0;

HKEY hKey = NULL;
DWORD dwDisp=0;
if(RegCreateKeyExW(hPrimKey, szSubKey, NULL, NULL,
0, KEY_ALL_ACCESS , NULL, &hKey, &dwDisp) == ERROR_SUCCESS)
{
RegSetValueExW(hKey, szValueName, NULL, REG_SZ, (BYTE*)szUtf8String, iUtf8Len);
RegCloseKey(hKey);
}

delete [] szUtf8String;
delete [] wChString;
}

//读出测试
{
HKEY hKey = NULL;
if(RegOpenKeyExW(hPrimKey, szSubKey, 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
{
//获取长度
DWORD dwType=0, iUtf8Len = 0;
RegQueryValueExW(hKey, szValueName, NULL, &dwType, NULL, &iUtf8Len);
//读入UTF8
CHAR *chUtf8 = new char[iUtf8Len + 1];
RegQueryValueExW(hKey, szValueName, NULL, &dwType, (BYTE*)chUtf8, &iUtf8Len);
chUtf8[iUtf8Len] = 0;

//UTF8-->Unicode
int iWLen = MultiByteToWideChar(CP_UTF8, 0, chUtf8, -1, NULL, 0);
WCHAR *wChString = new WCHAR[iWLen + 1];
MultiByteToWideChar(CP_UTF8, 0, chUtf8, -1, wChString, iWLen);
wChString[iWLen]= 0;

//Unicode--->GBK
int iGBKLen = WideCharToMultiByte(CP_GBK, 0, wChString, -1, NULL, 0, NULL, NULL);
CHAR *chGBK = new CHAR[iGBKLen + 1];
WideCharToMultiByte(CP_GBK, 0, wChString, -1, chGBK, iGBKLen, NULL, NULL);
chGBK[iGBKLen] = 0;

ASSERT(strcmp(srcGbk, chGBK) == 0);

delete [] chGBK;
delete [] wChString;
delete [] chUtf8;

RegCloseKey(hKey);
}
}


test_lockxxx 2019-03-23
  • 打赏
  • 举报
回复
使用 REG_BINARY 类型,在我的程序中写入,读取转换成utf-8的数据,测试发现,数据不会丢失。 但另一个exe文件在读取注册表项的时候,加了一个判断: REG_SZ,导致我的程序必须使用 REG_SZ。 苦恼...
test_lockxxx 2019-03-23
  • 打赏
  • 举报
回复
转换成utf-8编码后,结尾不缺少结束符 '\0' 其实问题应该改成: 为什么将 gbk编码的中文转换成utf-8编码,写入注册表项(REG_SZ)后,会出现数据丢失的情况。
test_lockxxx 2019-03-23
  • 打赏
  • 举报
回复
我的程序内部使用的是 gbk 编码,如果在写入注册表的时候,不转换成 utf-8,对于我的程序,是可以正常的写入和读取。 但是另一个程序由于使用的是 utf-8,他读取我写入的注册表项的内容,就会出现乱码。 为了解决这个问题,我在写入注册表的时候,将内容先转换成 utf-8,然后再写入注册表项(REG_SZ) 但是,发现有些中文转换成utf-8后,写入注册表会丢失数据。
zgl7903 2019-03-23
  • 打赏
  • 举报
回复
写入对吗? 是否缺少了结束符 0 ?
RegSetValueExW RegQueryValueEx 直接读写Unicode, 不要转码

test_lockxxx 2019-03-22
  • 打赏
  • 举报
回复
另一个程序在读取注册表项时,会判断注册表项的类型,必须为 REG_SZ,所以我的程序在存储的时候,必须使用 REG_SZ 类型。
@风轻云淡_ 2019-03-22
  • 打赏
  • 举报
回复
建议存注册表的时候,以GBK格式存储,读出来之后再转换为UTF8或者别的格式
  • 打赏
  • 举报
回复
使用REG_BINARY类型写二进制数据
test_lockxxx 2019-03-22
  • 打赏
  • 举报
回复
发现,将gbk字符串:"d:\新2" 转换成 utf-8 编码后,存储到注册过后, 数据就被改写了,问题就出在这里。

69,369

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧