I'm trying to get data from the URL address using WinInet.h
. Here is my simplified code:
LPCTSTR url = (LPCTSTR) "https://example.com"; // 2.9.1
HINTERNET connection = InternetOpenA(NULL, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
HINTERNET request = InternetOpenUrlA(connection, url, NULL, 0, INTERNET_FLAG_RELOAD, 0);
char status_code[10];
DWORD info_size = 10000;
HttpQueryInfoA(request, HTTP_QUERY_STATUS_CODE, status_code, &info_size, NULL);
DWORD size;
DWORD dwRead = 0;
InternetQueryDataAvailable(request, &size, 0, 0); // size = 5
char * buffer = new char[size]; // size = 5
InternetReadFile(request, buffer, size, &dwRead);
OutputDebugString(buffer); // 1.2.3ýýýý
InternetCloseHandle(connection);
InternetCloseHandle(request);
It works well, but the data on the URL address is 2.9.1
but the buffer returns 2.9.1ýýýý
.
If I try to print char after char, this is the result:
for (int i = 0; i < size; i++)
OutputDebugString(&buffer[i]);
char[0] = 2.9.1ýýýý
char[1] = .9.1ýýýý
char[2] = 9.1ýýýý
char[3] = .1ýýýý
char[4] = 1ýýýý
Can anyone explain to me why this is happening?
The data you're receiving is a C-style string, i.e. a null-character terminated array of characters. The important part here is that a string of 5 characters actually requires an array of size 6, for example:
"hello"
is made up of an array of 6 characters, 'h'
, 'e'
, 'l'
, 'l'
, 'o'
, '\0'
.
OutputDebugString
will go through the array printing the characters until it reaches a '\0'
.
In this case you're not allocating anywhere for the terminating '\0'
to go, so OutputDebugString
will keep going until there happens to be a '\0'
in memory (or until it reaches memory it's not allowed to access).
Change this bit:
char * buffer = new char[size]; // size = 5
InternetReadFile(request, buffer, size, &dwRead);
to be
char * buffer = new char[size + 1]; // size = 5, allocate 6 chars
InternetReadFile(request, buffer, size, &dwRead);
buffer [size] = '\0';