Kenny
Kenny

Reputation: 94

Adding char array to string in c++

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

Answers (5)

Software_Designer
Software_Designer

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

Zwerg
Zwerg

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

bames53
bames53

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

Yakk - Adam Nevraumont
Yakk - Adam Nevraumont

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

Pete Becker
Pete Becker

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

Related Questions