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);
这给了我错误:表达式必须具有整数或枚举类型。
我该如何解决这个问题?
答案 0 :(得分: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);
答案 1 :(得分: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的东西)的认可,只是一个简单的代码块,可以完成原始的代码块。
答案 2 :(得分: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字符串上没有做你想做的任何事情。通过使用std :: string()开始,添加原始C字符串会创建新的std :: strings。然后我们在最后调用.c_str()返回一个原始的C字符串,该字符串至少持续到你调用的函数结束。然后一切都被清理干净了。
现在,您的代码还有其他问题。 char site[]; scanf("%s", site);
调用未定义的行为,因为编译器不知道site
数组应该有多大。即使你给了site
一个大小,比如char site[100];
,这也就是等待发生的缓冲区溢出 - 使用scanf
这样就不建议了。
当读取字符串时,您需要一个函数来限制您读取到正在读取的缓冲区的数量,或者根据需要调整缓冲区的大小以适合您正在阅读的内容。
注意我假设代码实际上是C ++,标记为。
答案 3 :(得分: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
添加到一起,或者可以添加std::string
const char *
(因为std :: string在其自身和operator+
之间定义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());
答案 4 :(得分: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;
}