Hello everyone,

I just started learning c++ and I started with creating a programme that gets your wan ip adress.
Just because it covers some basic stuff.

Getting the content of the website works fine. But the parsing doesn't really work. If tried with sscanf, but it didn't work. Also using regex from the boost libraries didn't work. I think it's because that it uses stings and my output is a char.

So if anyone could give me a good and compact way to extract the ip out of the content, it would be very nice.
You can also give me other advice to improve my skills. :)

#include <windows.h>
#include <wininet.h>
#include <iostream>
#pragma comment (lib, "wininet.lib")
using namespace std;

HINTERNET hOpen, hFile;
char buffer[200];
DWORD ret;

int main() {
	hOpen = InternetOpen("Mozilla/5.0", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
	if (!hOpen) {
		cout << "error: no connection" << endl;
		return 0;
	}
	hFile = InternetOpenUrl(hOpen, "http://checkip.dyndns.org", NULL, 0, 0, 0);
	if (!hFile) {
		cout << "error: 'check website' offline" << endl;
		return 0;
	}
	InternetReadFile(hFile, buffer, sizeof(buffer), &ret);
	cout << buffer;
	return 0;
}

Thx in advance

Recommended Answers

All 10 Replies

I made some changes. I hope I did it well.
I didn't know how to check the ret result though.

#include <windows.h>
#include <wininet.h>
#include <iostream>
#pragma comment (lib, "wininet.lib")
using namespace std;

HINTERNET hOpen, hFile;
char buffer[200];
DWORD ret;

int main() {
	if ((hOpen = InternetOpen("Mozilla/5.0", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0)) == NULL) {
		cout << "error: no connection" << endl;
		return 0;
	}
	if ((hFile = InternetOpenUrl(hOpen, "http://checkip.dyndns.org", NULL, 0, 0, 0)) == NULL) {
		cout << "error: 'check website' offline" << endl;
		return 0;
	}
	if ((InternetReadFile(hFile, buffer, sizeof(buffer), &ret)) == NULL) {
		cout << "error: reading failed" << endl;
		return 0;
	}
	printf("%s", buffer);
	return 0;
}

BTW, this is my output that has to be parsed.

<html><head><title>Current IP Check</title></head><body>Current IP Address: 83.109.18.76</body></html>

Use a couple of substrings to get the IP address since you know its always going to say, Current IP Address: you can use find to find that string, it will return the position in the string of the first character, you can then add 20 to that to give you the position of the space before the first number in the ip address, then use find again to get the first occurence of '<' from the position you have aquried from the first find. And finally use the to positions to get yourself a substring of the ip address

Chris

It returns BOOL, not a pointer.

// -1 makes sure we can add a \0 later on
if ( InternetReadFile(hFile, buffer, sizeof(buffer)-1, &ret) )
{
    char *p;
    buffer[ret] = '\0';  // make sure there is a \0 there.
    if ( (p=strstr( buffer, "Current IP Address:" )) != NULL ) {
        printf("Getting closer to %s\n", p );
    }
}
else
{
   // call GetLastError.
}

Thx for all the help so far.
I'm trying to use the find method, but it doesn't work because i'm working with a char and not with a string.

#include <windows.h>
#include <wininet.h>
#include <iostream>
#pragma comment (lib, "wininet.lib")
using namespace std;

HINTERNET hOpen, hFile;
char buffer[200], ip[16], *extract;
DWORD ret;
size_t pos1, pos2;

int main() {
	if ((hOpen = InternetOpen("Mozilla/5.0", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0)) == NULL) {
		cout << "error: no connection" << endl;
		return 0;
	}
	if ((hFile = InternetOpenUrl(hOpen, "http://checkip.dyndns.org", NULL, 0, 0, 0)) == NULL) {
		cout << "error: 'check website' offline" << endl;
		return 0;
	}
	if (InternetReadFile(hFile, buffer, sizeof(buffer), &ret)) {
		buffer[ret] = '\0';
		if ((extract = strstr(buffer, "Address:")) != NULL) {
			pos1 = extract.find(":");
			pos2 = extract.find("<");
			ip = extract.substr(pos1+1,pos2);
			printf("%s",ip);
		}
	}
	else {
		cout << "error: reading failed" << endl;
		return 0;
	}
	return 0;
}

I see you forgot a -1

I first didn't notice it. Thx

I found a way to do it, but I'm sure there's a more efficient way.
Maybe someone can give me some advice to improve that.

#include <windows.h>
#include <wininet.h>
#include <iostream>
#pragma comment (lib, "wininet.lib")
using namespace std;

HINTERNET hOpen, hFile;
char buffer[200], *pch;
DWORD ret;

int main() {
	if ((hOpen = InternetOpen("Mozilla/5.0", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0)) == NULL) {
		cout << "error: no connection" << endl;
		return 0;
	}
	if ((hFile = InternetOpenUrl(hOpen, "http://checkip.dyndns.org", NULL, 0, 0, 0)) == NULL) {
		cout << "error: 'check website' offline" << endl;
		return 0;
	}
	if (InternetReadFile(hFile, buffer, sizeof(buffer)-1, &ret)) {
		buffer[ret] = '\0';
		pch = strtok(buffer,"< ");
		while (pch != NULL) {
			if (strstr(pch, ".")) {
				printf ("%s",pch);
				pch = strtok(NULL,"< ");
				break;
			}
			pch = strtok(NULL,"< ");
		}
	}
	else {
		cout << "error: reading failed" << endl;
		return 0;
	}
	return 0;
}

Only that if this is C++, you should do

buffer[ret] = '\0';
std::string s = buffer;
// now use appropriate std::string methods

You also need to get rid of all those global variables.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.