Reputation: 94
char site[];
scanf("%s", site);
send(sock,"GET / HTTP/1.1\r\nHost: " + site + "\r\nConnection: close\r\n\r\n", strlen("GET / HTTP/1.1\r\nHost: " + site + "\r\nConnection: close\r\n\r\n"),0);
This gives me the error: expression must have integral or enum type.
How can i fix this?
Upvotes: 1
Views: 3076
Reputation: 8587
Another GET
implementation.
char *get_http= new char[256];
memset(get_http,' ', sizeof(get_http) );
strcpy(get_http,"GET / HTTP/1.1\r\nHost: ");
strcat(get_http,url);
strcat(get_http,"\r\nConnection: close\r\n\r\n");
.
.
send(Socket,get_http, strlen(get_http),0 );
Sample Winsock console HTML Browser code:
#include <winsock2.h>
#include <windows.h>
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cctype>
#include <locale>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
string website_HTML;
locale local;
//***************************
void get_Website(char *url );
//***************************
int main ()
{
get_Website("www.msn.com" );
for (size_t i=0; i<website_HTML.length(); ++i) website_HTML[i]= tolower(website_HTML[i],local);
cout <<website_HTML;
cout<<"\n\n";
return 0;
}
//***************************
void get_Website(char *url )
{
WSADATA wsaData;
SOCKET Socket;
SOCKADDR_IN SockAddr;
int lineCount=0;
int rowCount=0;
struct hostent *host;
char *get_http= new char[256];
memset(get_http,' ', sizeof(get_http) );
strcpy(get_http,"GET / HTTP/1.1\r\nHost: ");
strcat(get_http,url);
strcat(get_http,"\r\nConnection: close\r\n\r\n");
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
{
cout << "WSAStartup failed.\n";
system("pause");
//return 1;
}
Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
host = gethostbyname(url);
SockAddr.sin_port=htons(80);
SockAddr.sin_family=AF_INET;
SockAddr.sin_addr.s_addr = *((unsigned long*)host->h_addr);
cout << "Connecting to "<< url<<" ...\n";
if(connect(Socket,(SOCKADDR*)(&SockAddr),sizeof(SockAddr)) != 0)
{
cout << "Could not connect";
system("pause");
//return 1;
}
cout << "Connected.\n";
send(Socket,get_http, strlen(get_http),0 );
char buffer[10000];
int nDataLength;
while ((nDataLength = recv(Socket,buffer,10000,0)) > 0)
{
int i = 0;
while (buffer[i] >= 32 || buffer[i] == '\n' || buffer[i] == '\r')
{
website_HTML+=buffer[i];
i += 1;
}
}
closesocket(Socket);
WSACleanup();
delete[] get_http;
}
Upvotes: 0
Reputation: 11
As noted in the other answer, the code you posted is straight C. In C++ you normally favor std::string to the C-style char arrays and std::cin to the C-style scanf(). A more C++ way would look like this
std::string input;
std::cin >> input;
std::string out = "GET / HTTP/1.1\r\nHost: " + input + "\r\nConnection: close\r\n\r\n";
send(sock, out.c_str(), out.size(), 0);
Upvotes: 1
Reputation: 88155
char site[];
This code is not legal. Your compiler should be producing an error such as:
main.cpp:5:10: error: definition of variable with array type needs an explicit size or an initializer
char site[];
^
Because in C++ the built-in arrays have a fixed size that is part of their type. If you want a resizable array you should use std::vector
for the general case and std::string
for strings.
scanf("%s", site);
If char site[]
is working your compiler probably creates an array of size zero, so reading anything into it results in a buffer overflow.
send(sock,"GET / HTTP/1.1\r\nHost: " + site + "\r\nConnection: close\r\n\r\n", strlen("GET / HTTP/1.1\r\nHost: " + site + "\r\nConnection: close\r\n\r\n"),0);
This should result in another error along the lines of:
main.cpp:10:42: error: invalid operands to binary expression ('const char *' and 'char *')
send(sock,"GET / HTTP/1.1\r\nHost: " + site + "\r\nConnection: close\r\n\r\n", strlen("GET / HTTP/1.1\r\nHost: " + site + "\r\nConnection: close\r\n\r\n"),0);
~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~
In C++ you cannot simply add arrays together. Again, arrays in C++ are fixed size objects. You can however add std::strings
together, or you can add a std::string
with a const char *
(because std::string defines operator+
between itself and const char *
).
std::string site;
site = getURL(); // you'll have to implement this, including both getting the string from the user and validating that the user isn't entering in something tricky that will cause security problems
std::string query = "GET / HTTP/1.1\r\nHost: " + site + "\r\nConnection: close\r\n\r\n";
send(sock, query.c_str(), query.size());
Upvotes: 0
Reputation: 275310
Change this:
"GET / HTTP/1.1\r\nHost: " + site + "\r\nConnection: close\r\n\r\n", strlen("GET / HTTP/1.1\r\nHost: " + site + "\r\nConnection: close\r\n\r\n"
to this:
(std::string() +"GET / HTTP/1.1\r\nHost: " + site + "\r\nConnection: close\r\n\r\n", strlen("GET / HTTP/1.1\r\nHost: " + site + "\r\nConnection: close\r\n\r\n").c_str()
for an absolutely minimal change to make that line of code compile and do what you probably want.
operator+ on raw C strings doesn't do anything you want to do. By starting off with a std::string(), adding raw C strings creates new std::strings. We then call .c_str() at the end to go back to a raw C string who lasts at least until the function you are calling finishes. Then everything is cleaned up.
Now, your code has other problems. char site[]; scanf("%s", site);
invokes undefined behavior, as the compiler has no idea how big the site
array should be. Even if you gave site
a size, like char site[100];
, this would be a buffer-overflow waiting to happen -- using scanf
like that is NOT advised.
When reading a string, you either need a function that limits the amount you read to the buffer you are reading to, or which resizes the buffer as needed to fit what you are reading.
Note I'm assuming that the code is actually C++, as tagged.
Upvotes: 0
Reputation: 76245
Although this is tagged C++, the code is straight C. There are two problems: first, site
is an incomplete type; you need to give it a size; second, in C you can't just jam strings together with '+'. You need to use strcat
:
char site[128];
char cmd[128];
scanf("%s", site);
strcpy(cmd, "GET / HTTP/1.1\r\nHost: ");
strcat(cmd, site);
strcat(cmd, "\r\nConnection: close\r\n\r\n");
That's not an endorsement of the style (nor of the \r\n stuff), just a simple code block that does what the original didn't.
Upvotes: 0