[英]Read registry and output to console with C++
作为 C++ 初学者,我需要你的帮助!
我目前正在开发一个程序,该程序应该能够读取注册表项及其值并将其写入向量数组以进行进一步处理。
但是现在我有一个问题,即控制台上的 output 中神秘地显示变音符号。 我怀疑这是因为使用了错误的字符编码。 经过一番研究,我发现了 function "SetConsoleOutputCP(65001)",它应该将控制台的 output 设置为 UTF8。
不幸的是,如果使用 Unicode 兼容函数来读取注册表,则 output 现在会在变音符号上中断。 在第二种情况下,控制台在使用 ANSI 兼容功能时只是隐藏了变音符号。 我在这里做错了什么,如何从注册表和 output 正确读取变音符号到控制台?
另外,我想稍后将元音变音正确写入 CSV 文件。 我还需要注意这里有什么特别的吗?
您可以在下面找到我的代码以及一些评论。 感谢所有帮助者!
#include <iostream>
#include <string>
#include <vector>
#include <windows.h>
/**
* @brief Function to read an registry key to a vector of strings. Registry function will be called as unicode compatible version e.g. RegQueryValueExW (W at the end). This function is overloaded and exists with a different parameter list as well.
*
* @param rootKey Standard hkey for the root key value
* @param subKey Specific path for a subkey value
* @param value The value name whose value is to be read
* @return std::vector<std::wstring>
*/
std::vector<std::wstring> regMultiSzToVector(HKEY rootKey, LPCWSTR subKey, LPCWSTR value) {
HKEY hkey;
DWORD type, size;
std::vector<std::wstring> target;
// Open registry key and write it to hkey variable
if (RegOpenKeyEx(rootKey, subKey, 0, KEY_READ | KEY_WOW64_64KEY, &hkey) != ERROR_SUCCESS)
exit(1);
// Get type and necessary memory size
if (RegQueryValueExW(hkey, value, NULL, &type, NULL, &size) != ERROR_SUCCESS)
exit(1);
if (type == REG_MULTI_SZ) {
std::vector<wchar_t> temp(size / sizeof(wchar_t));
if (RegQueryValueExW(hkey, value, NULL, NULL, reinterpret_cast<LPBYTE>(&temp[0]), &size) != ERROR_SUCCESS)
exit(1);
// Writing value from registry key to string array
size_t index = 0;
size_t len = wcslen(&temp[0]);
while (len > 0) {
target.push_back(&temp[index]);
index += len + 1;
len = wcslen(&temp[index]);
}
}
// Closing registry key (see API)
RegCloseKey(hkey);
return target;
}
/**
* @brief Function to read an registry key to a vector of strings. Registry function will be called as ansi compatible version e.g. RegQueryValueExA (A at the end). This function is overloaded and exists with a different parameter list as well.
*
* @param rootKey Standard hkey for the root key value
* @param subKey Specific path for a subkey value
* @param value The value name whose value is to be read
* @return std::vector<std::string>
*/
std::vector<std::string> regMultiSzToVector(HKEY rootKey, LPCSTR subKey, LPCSTR value) {
HKEY hkey;
DWORD type, size;
std::vector<std::string> target;
// Open registry key and write it to hkey variable
if (RegOpenKeyExA(rootKey, subKey, 0, KEY_READ | KEY_WOW64_64KEY, &hkey) != ERROR_SUCCESS)
exit(1);
// Get type and necessary memory size
if (RegQueryValueExA(hkey, value, NULL, &type, NULL, &size) != ERROR_SUCCESS)
exit(1);
if (type == REG_MULTI_SZ) {
std::vector<char> temp(size);
if (RegQueryValueExA(hkey, value, NULL, NULL, reinterpret_cast<LPBYTE>(&temp[0]), &size) != ERROR_SUCCESS)
exit(1);
// Writing value from registry key to string array
size_t index = 0;
size_t len = strlen(&temp[0]);
while (len > 0) {
target.push_back(&temp[index]);
index += len + 1;
len = strlen(&temp[index]);
}
}
// Closing registry key (see API)
RegCloseKey(hkey);
return target;
}
int main(int argc, char const* argv[]) {
// Saving function return values to vectors
std::vector<std::wstring> result1 = regMultiSzToVector(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib\\007", L"Counter");
std::vector<std::string> result2 = regMultiSzToVector(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib\\007", "Counter");
// Printing String values from first and second vector
printf("Vector 1: \n");
for (auto &e : result1) {
std::wcout << e << std::endl;
}
printf("\n\n\n Vector 2: \n");
for (auto &e : result2) {
std::cout << e << std::endl;
}
return 0;
}
如果要使用 CP65001 (UTF-8),则还需要将 utf-16 编码的wstring
转换为 utf-8 编码的字符串。
这是一个简单的方法: https://stackoverflow.com/a/12903901/347508
我只对您的代码做了一些小的修改:
#include <iostream>
#include <string>
#include <vector>
#include <windows.h>
#include <codecvt>
#pragma comment(lib, "user32")
#pragma comment(lib, "Advapi32")
// utf-8 conversion from https://stackoverflow.com/a/12903901/347508
// convert UTF-8 string to wstring
std::wstring utf8_to_wstring (const std::string& str)
{
std::wstring_convert<std::codecvt_utf8<wchar_t>> myconv;
return myconv.from_bytes(str);
}
// convert wstring to UTF-8 string
std::string wstring_to_utf8 (const std::wstring& str)
{
std::wstring_convert<std::codecvt_utf8<wchar_t>> myconv;
return myconv.to_bytes(str);
}
/**
* @brief Function to read an registry key to a vector of strings. Registry function will be called as unicode compatible version e.g. RegQueryValueExW (W at the end). This function is overloaded and exists with a different parameter list as well.
*
* @param rootKey Standard hkey for the root key value
* @param subKey Specific path for a subkey value
* @param value The value name whose value is to be read
* @return std::vector<std::wstring>
*/
std::vector<std::wstring> regMultiSzToVector(HKEY rootKey, LPCWSTR subKey, LPCWSTR value) {
HKEY hkey;
DWORD type, size;
std::vector<std::wstring> target;
// Open registry key and write it to hkey variable
if (RegOpenKeyExW(rootKey, subKey, 0, KEY_READ | KEY_WOW64_64KEY, &hkey) != ERROR_SUCCESS)
exit(1);
// Get type and necessary memory size
if (RegQueryValueExW(hkey, value, NULL, &type, NULL, &size) != ERROR_SUCCESS)
exit(1);
if (type == REG_MULTI_SZ) {
std::vector<wchar_t> temp(size / sizeof(wchar_t));
if (RegQueryValueExW(hkey, value, NULL, NULL, reinterpret_cast<LPBYTE>(&temp[0]), &size) != ERROR_SUCCESS)
exit(1);
// Writing value from registry key to string array
size_t index = 0;
size_t len = wcslen(&temp[0]);
while (len > 0) {
target.push_back(&temp[index]);
index += len + 1;
len = wcslen(&temp[index]);
}
}
// Closing registry key (see API)
RegCloseKey(hkey);
return target;
}
int main(int argc, char const* argv[]) {
// Saving function return values to vectors
std::vector<std::wstring> res = regMultiSzToVector(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion", L"hansi");
// Printing String values from first and second vector
printf("Result: \n");
for (auto &e : res) {
std::wcout << "* utf-16=" << e << std::endl;
std::cout << " utf-8 =" << wstring_to_utf8(e) << std::endl;
}
return 0;
}
Output:
C:\Users\Hansi>chcp 850
Active code page: 850
C:\Users\Hansi>cl /EHsc reg_test.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.28.29910 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
reg_test.cpp
Microsoft (R) Incremental Linker Version 14.28.29910.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:reg_test.exe
reg_test.obj
C:\Users\Hansi>reg_test.exe
Result:
* utf-16=Íl
utf-8 =Öl
* utf-16=H÷ren
utf-8 =H├Âren
* utf-16=T³re
utf-8 =T├╝re
* utf-16=Da▀
utf-8 =Daß
C:\Users\Hansi>chcp 65001
Active code page: 65001
C:\Users\Hansi>reg_test.exe
Result:
* utf-16=l
utf-8 =Öl
* utf-16=Hren
utf-8 =Hören
* utf-16=T utf-8 =Türe
utf-8 =Daß
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.