Lienau
Lienau

Reputation: 1353

InternetReadFile to Char* in C

I'm having a bit of a problem with the following code. I've seen tons of examples for using InternetReadFile to save to a file. But I cant find one, or get it to work for a char[]. I want to add the szBuffer up to get holdBuff, and then set content equal to holdBuff.

#include <stdio.h>
#include <tchar.h>
#include <string.h>
#include <windows.h>
#include <WinInet.h>

HINTERNET hSession;
void urlToChar(char* url, char** content);

int main()
{
    hSession = InternetOpen("Mozilla/4.0 (compatible) Poison", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
    char* content;
    urlToChar("http://google.com/", &content);
    printf("%s",content);
    return 0;
}

void urlToChar(char* url, char** content)
{
    HINTERNET hConnect = InternetConnect(hSession, _T(""),INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1);
    HINTERNET hRequest = InternetOpenUrl(hSession, url, NULL, 0, 0, 0);
    if (hRequest)
    {
        char holdBuff[] = "";
        char szBuff[1025];
        memset(szBuff, 0x00, sizeof(szBuff));
        DWORD bytesRead;
        while (InternetReadFile(hRequest, szBuff, 1024, &bytesRead) == TRUE && bytesRead > 0)
        {
            // Cat szBuff to holdBuff
            memset(szBuff, 0x00, sizeof(szBuff));
        }
        *content = holdBuff;
        // memset(holdBuff, 0x00, sizeof(holdBuff));  <-- Need this?
    }
    InternetCloseHandle(hRequest);
    InternetCloseHandle(hConnect);
}

Upvotes: 1

Views: 6876

Answers (2)

vincent
vincent

Reputation: 1

void urlToChar(char* url, char** content)
{
    HINTERNET hConnect = InternetConnect(hSession, _T(""),INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1);
    HINTERNET hRequest = InternetOpenUrl(hSession, url, NULL, 0, 0, 0);
    if (hRequest)
    {
        char holdBuff[] = "";   //do not use fixed size char array and allocate buffer in stack,you can allocate large enough buffer in heap,but recommend you can use string or CString
        char szBuff[1025];
        memset(szBuff, 0x00, sizeof(szBuff));
        DWORD bytesRead;
        while (InternetReadFile(hRequest, szBuff, 1024, &bytesRead) == TRUE && bytesRead > 0)
        {
            // Cat szBuff to holdBuff
            //strcat when using char array
            // operator+ when using stl string
            // [stl string][1]
            memset(szBuff, 0x00, sizeof(szBuff));
        }
        *content = holdBuff;
        // memset(holdBuff, 0x00, sizeof(holdBuff));  <-- Need this?
    }
    InternetCloseHandle(hRequest);
    InternetCloseHandle(hConnect);
}

Upvotes: 0

chrisaycock
chrisaycock

Reputation: 37930

The variable declaration

char xyz[] = "Hello World!";

will tell the compiler to put the contents of the string on the stack. Of course, the stack goes away when your function returns.

So in your case:

char holdBuff[] = "";
...
*content = holdBuff;

This tells the compiler to create a string of length one (the NULL terminator) as a local variable. Just because you've set the value of content to holdBuff doesn't mean that what holdBuff was pointing exists anymore.

You have to correct two things. Firstly, you must use strcpy() or similar function. Second, you must allocate sufficient space for holdBuff.

Example:

char holdBuff[4096];    // or some other sufficiently large size
...
*content = malloc (strlen(holdBuff) + 1);
strcpy (*content, holdBuff);

You'll then need to free(content) in main() once you're finished with it.


Now, for how to actually do the concatenation: Your performance will be much better if you forget about using szBuff at all and just write directly to holdBuff.

char* temp = holdBuff;
while (InternetReadFile(hRequest, temp, 1024, &bytesRead) == TRUE && bytesRead > 0)
{
    temp += bytesRead;
}
*temp = '\0';    // manually append NULL terminator

Now holdBuff will have the data you want with no need for intermediary concatenation.

Upvotes: 2

Related Questions