Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
HttpSendRequest-POST数据不支持Unicode 我正在研究一种C++代理,它将使用HTTPSeDebug请求()将信息(例如系统主机名)回放到中央服务器上。我想让它发回的信息之一是操作系统。我创建了以下函数来获取系统主机名 wstring getOS() { HKEY key; RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_QUERY_VALUE, &key); // Obtains Registry handle DWORD type; wchar_t buffer[MAX_PATH]; // MAX_PATH = 260 - The system hostname should never exceed this value DWORD size = sizeof(buffer); RegQueryValueEx(key, L"ProductName", NULL, &type, (LPBYTE)&buffer, &size); // Queries Registry key - stores value in "buffer" wstring os(buffer); // Converts from C-style character array to wstring return os; // Returns wstring to caller }_C++_Unicode - Fatal编程技术网

HttpSendRequest-POST数据不支持Unicode 我正在研究一种C++代理,它将使用HTTPSeDebug请求()将信息(例如系统主机名)回放到中央服务器上。我想让它发回的信息之一是操作系统。我创建了以下函数来获取系统主机名 wstring getOS() { HKEY key; RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_QUERY_VALUE, &key); // Obtains Registry handle DWORD type; wchar_t buffer[MAX_PATH]; // MAX_PATH = 260 - The system hostname should never exceed this value DWORD size = sizeof(buffer); RegQueryValueEx(key, L"ProductName", NULL, &type, (LPBYTE)&buffer, &size); // Queries Registry key - stores value in "buffer" wstring os(buffer); // Converts from C-style character array to wstring return os; // Returns wstring to caller }

HttpSendRequest-POST数据不支持Unicode 我正在研究一种C++代理,它将使用HTTPSeDebug请求()将信息(例如系统主机名)回放到中央服务器上。我想让它发回的信息之一是操作系统。我创建了以下函数来获取系统主机名 wstring getOS() { HKEY key; RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_QUERY_VALUE, &key); // Obtains Registry handle DWORD type; wchar_t buffer[MAX_PATH]; // MAX_PATH = 260 - The system hostname should never exceed this value DWORD size = sizeof(buffer); RegQueryValueEx(key, L"ProductName", NULL, &type, (LPBYTE)&buffer, &size); // Queries Registry key - stores value in "buffer" wstring os(buffer); // Converts from C-style character array to wstring return os; // Returns wstring to caller },c++,unicode,C++,Unicode,此函数将使用注册表获取操作系统,并将其存储为wstring。然后,我想将返回的“os”wstring传递给下面的post()函数,但我注意到,对于HTTP post数据,必须使用字符串而不是wstring。下面是my post()函数的代码: void post() { HINTERNET hInternetOpen = InternetOpen(userAgent.c_str(), INTERNET_OPEN_TYPE_PROXY, L"http://127.0.0.1:9999",

此函数将使用注册表获取操作系统,并将其存储为wstring。然后,我想将返回的“os”wstring传递给下面的post()函数,但我注意到,对于HTTP post数据,必须使用字符串而不是wstring。下面是my post()函数的代码:

void post()
{
     HINTERNET hInternetOpen = InternetOpen(userAgent.c_str(), INTERNET_OPEN_TYPE_PROXY, L"http://127.0.0.1:9999", NULL, 0);
     HINTERNET hInternetConnect = InternetConnect(hInternetOpen, host.c_str(), INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
     HINTERNET hHttpOpenRequest = HttpOpenRequest(hInternetConnect, L"POST", file.c_str(), NULL, NULL, NULL, 0, 0);

     wstring headers = L"Content-Type: application/x-www-form-urlencoded"; // Content-Type is necessary to POST

     string postData = "os="; // Why does this have to be a string and not a wstring?

     HttpSendRequest(hHttpOpenRequest, headers.c_str(), headers.length(), (LPVOID)postData.c_str(), postData.size());

     InternetCloseHandle(hInternetOpen);
     InternetCloseHandle(hInternetConnect);
     InternetCloseHandle(hHttpOpenRequest);
}
如果我尝试将“postData”设置为wstring,我会得到如下图所示的内容:

有人能解释一下将wstring作为POST数据的最简单方法吗?

HttpSendRequest()
只知道原始字节,而不知道字符串。您可以使用
std::wstring
发送UTF-16数据,但必须通过
内容类型
标题中的
字符集
属性告诉服务器您正在发送UTF-16

wstring headers = L"Content-Type: application/x-www-form-urlencoded; charset=utf-16";

// TODO: don't forget to URL-encode the value from getOS() to
// escape reserved characters, including '=' and '&'...
wstring postData = L"os=" + getOS();

HttpSendRequest(hHttpOpenRequest, headers.c_str(), headers.length(),
    postData.c_str(), postData.length() * sizeof(wchar_t));
注意上面使用的
sizeof(wchar\t)
。在屏幕截图中,您的嗅探器显示的是原始数据,它显示的数据是UTF-16的样子,但是您只看到了
wstring
数据的一半,因为您正在将
HttpSendRequest()
dwOptionalLength
参数设置为字符计数(7),而不是字节计数(14):

dwOptionalLength[in]
可选数据的大小,以字节为单位。如果没有要发送的可选数据,则此参数可以为零

使用
std::string
时,字符计数和字节计数是相同的值

您真正应该发送的是UTF-8而不是UTF-16,例如:

string Utf8Encode(const wstring &wstr)
{
    // NOTE: C++11 has built-in support for converting between
    // UTF-8 and UTF-16.  See the std::wstring_convert class...
    /*
    wstring_convert<codecvt_utf8_utf16<wchar_t>> conv;
    return conv.to_bytes(wstr);
    */

    string out;
    int len = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), wstr.length(), NULL, 0, NULL, NULL);
    if (len > 0)
    {
        out.resize(len);
        WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), wstr.length(), &out[0], len, NULL, NULL);
    }
    return out;
}
HttpSendRequest()
只知道原始字节,不知道字符串。您可以使用
std::wstring
发送UTF-16数据,但必须通过
内容类型
标题中的
字符集
属性告诉服务器您正在发送UTF-16

wstring headers = L"Content-Type: application/x-www-form-urlencoded; charset=utf-16";

// TODO: don't forget to URL-encode the value from getOS() to
// escape reserved characters, including '=' and '&'...
wstring postData = L"os=" + getOS();

HttpSendRequest(hHttpOpenRequest, headers.c_str(), headers.length(),
    postData.c_str(), postData.length() * sizeof(wchar_t));
注意上面使用的
sizeof(wchar\t)
。在屏幕截图中,您的嗅探器显示的是原始数据,它显示的数据是UTF-16的样子,但是您只看到了
wstring
数据的一半,因为您正在将
HttpSendRequest()
dwOptionalLength
参数设置为字符计数(7),而不是字节计数(14):

dwOptionalLength[in]
可选数据的大小,以字节为单位。如果没有要发送的可选数据,则此参数可以为零

使用
std::string
时,字符计数和字节计数是相同的值

您真正应该发送的是UTF-8而不是UTF-16,例如:

string Utf8Encode(const wstring &wstr)
{
    // NOTE: C++11 has built-in support for converting between
    // UTF-8 and UTF-16.  See the std::wstring_convert class...
    /*
    wstring_convert<codecvt_utf8_utf16<wchar_t>> conv;
    return conv.to_bytes(wstr);
    */

    string out;
    int len = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), wstr.length(), NULL, 0, NULL, NULL);
    if (len > 0)
    {
        out.resize(len);
        WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), wstr.length(), &out[0], len, NULL, NULL);
    }
    return out;
}

为什么你说“必须使用字符串而不是wstring”?如果我尝试使用wstring而不是字符串,它会弄乱POST数据(请参阅随附的屏幕截图)。你希望通过网络发送什么?utf8?请参见此处
size()
返回字符串中的字符数,而不是它们占用的内存量。如果您在
wstring
上调用
size()
,就像在代码中当前使用的
string
上一样,那么您就做错了。@captain不经意地感谢您,我已将其改为使用.length()而不是.size()。为什么您说“必须使用string而不是wstring”?如果我尝试使用wstring而不是string,它会弄乱POST数据(见附件屏幕截图)。您希望通过网络发送什么?utf8?请参见此处
size()
返回字符串中的字符数,而不是它们占用的内存量。如果您在
wstring
上调用
size()
,就像您在代码中当前使用的
字符串上一样,那么您就做错了。@captain不经意的谢谢您,我已将它改为使用.length()而不是.size()。您就是那个人!这是可行的,应该是公认的答案。如果我有足够的声誉,我会投票给它的:/非常感谢你!我只是点击了复选标记。如果这不起作用,请告诉我。再次感谢你,你就是那个男人!这是可行的,应该是公认的答案。如果我有足够的声誉,我会投票给它的:/非常感谢你!我只是点击了复选标记。如果这不起作用,请告诉我。再次感谢。