1
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?

6
  • Use std::string and using + works fine. Commented Oct 28, 2012 at 18:41
  • Isn't there a way to fix this? Without some fancy things. Commented Oct 28, 2012 at 18:42
  • Well, you'd have to use strcat. std::string is much more safe and useful than it is "fancy", though. Commented Oct 28, 2012 at 18:44
  • 4
    @Kenny std::string is about as unfancy as C++ gets. Commented Oct 28, 2012 at 18:45
  • I don't know how to use that =( Commented Oct 28, 2012 at 18:48

5 Answers 5

1

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);
Sign up to request clarification or add additional context in comments.

Comments

0

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.

2 Comments

That is improper use of scanf -- you do not guard against buffer overflows. At the very least, you need scanf("%128s", site); site[127]='\0';, and in practice you need to dynamically allocate a buffer long enough to store the string you read from your input, and dynamically allocate cmd to be long enough to fit everything in question.
@Yakk - as I said, this is not an endorsement of the style. It fixes the two errors that prevented the code from doing anything at all.
0

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.

Comments

0
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());

Comments

0

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;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.