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

回复:
user: user-0
content: 这也许是一个无解的问题。  结贴，感谢大家回复。

user: user-0
content: @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  为什么数据变了？

user: user-1
content: 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);     }   }

user: user-0
content: 使用 REG_BINARY 类型，在我的程序中写入，读取转换成utf-8的数据，测试发现，数据不会丢失。  但另一个exe文件在读取注册表项的时候，加了一个判断： REG_SZ，导致我的程序必须使用 REG_SZ。  苦恼...

user: user-0
content: 转换成utf-8编码后，结尾不缺少结束符 '\0'  其实问题应该改成：  为什么将 gbk编码的中文转换成utf-8编码，写入注册表项(REG_SZ)后，会出现数据丢失的情况。

user: user-0
content: 我的程序内部使用的是 gbk 编码，如果在写入注册表的时候，不转换成 utf-8，对于我的程序，是可以正常的写入和读取。  但是另一个程序由于使用的是 utf-8，他读取我写入的注册表项的内容，就会出现乱码。  为了解决这个问题，我在写入注册表的时候，将内容先转换成 utf-8，然后再写入注册表项(REG_SZ)  但是，发现有些中文转换成utf-8后，写入注册表会丢失数据。

user: user-1
content: 写入对吗？ 是否缺少了结束符 0 ？ RegSetValueExW  RegQueryValueEx 直接读写Unicode， 不要转码

user: user-0
content: 另一个程序在读取注册表项时，会判断注册表项的类型，必须为 REG_SZ，所以我的程序在存储的时候，必须使用 REG_SZ 类型。

user: user-2
content: 建议存注册表的时候,以GBK格式存储,读出来之后再转换为UTF8或者别的格式

user: user-3
content: 使用REG_BINARY类型写二进制数据

user: user-0
content: 发现，将gbk字符串："d:\新2"  转换成 utf-8 编码后，存储到注册过后， 数据就被改写了，问题就出在这里。