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

这给了我错误:表达式必须具有整数或枚举类型。

我怎样才能解决这个问题?

4

5 回答 5

1

如另一个答案中所述,您发布的代码是纯 C。在 C++ 中,您通常偏爱 std::string 到 C 样式的 char 数组,而 std::cin 偏爱 C 样式的 scanf()。一个更 C++ 的方式看起来像这样

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);
于 2012-10-28T19:05:35.337 回答
0
char site[];

此代码不合法​​。您的编译器应该会产生错误,例如:

main.cpp:5:10: error: definition of variable with array type needs an explicit size or an initializer
    char site[];
         ^

因为在 C++ 中,内置数组具有作为其类型一部分的固定大小。如果您想要一个可调整大小的数组,您应该将std::vector其用于一般情况和std::string字符串。

scanf("%s", site);

如果char 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);

这应该会导致另一个错误,如下所示:

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);
              ~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~

在 C++ 中,您不能简单地将数组相加。同样,C++ 中的数组是固定大小的对象。但是,您可以添加std::strings在一起,或者您可以添加 astd::string和 a const char *(因为 std::stringoperator+在自身和 之间定义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());
于 2012-10-28T19:04:38.287 回答
0

另一种GET实现。

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

示例 Winsock 控制台 HTML 浏览器代码:

#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;
}
于 2012-10-28T19:59:27.117 回答
0

虽然这是标记C++,但代码是直C。有两个问题:第一,site是一个不完整的类型;你需要给它一个大小;其次,在 C 语言中,您不能只将字符串与 '+' 组合在一起。您需要使用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");

这不是对风格的认可(也不是 \r\n 的东西),只是一个简单的代码块,它完成了原始代码没有做的事情。

于 2012-10-28T18:55:10.447 回答
0

改变这个: "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"

对此:

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

进行绝对最小的更改以使该行代码编译并执行您可能想要的操作。

原始 C 字符串上的 operator+ 不会做任何你想做的事情。从 std::string() 开始,添加原始 C 字符串会创建新的 std::strings。然后我们在最后调用 .c_str() 以返回原始 C 字符串,该字符串至少持续到您调用的函数完成。然后一切都清理干净了。

现在,您的代码还有其他问题。 调用未定义的行为,因为编译器不知道数组应该有char site[]; scanf("%s", site);多大。site即使你给出了site一个大小,比如char site[100];,这将是一个等待发生的缓冲区溢出——scanf不建议这样使用。

读取字符串时,您需要一个函数来限制您读取的缓冲区的数量,或者根据需要调整缓冲区的大小以适应您正在阅读的内容。

注意我假设代码实际上是 C++,如标记。

于 2012-10-28T19:01:59.490 回答