在我的源代码中,有以下代码段:
while ((cmd=getchar()) != EOF)
{
switch(cmd)
{
case '1':
printf("pls input the data to be sent: \n");
char data[100];
gets(data);
send_data(sd_cli, data, strlen(data), &svr_addr);
pcap_packet = pcap_next(pcap_handler, &pcap_header);
if(pcap_packet !=NULL)
printf("capture one packet with length of %d\n", pcap_header.len);
analyze_pcap_pkt(pcap_packet, &ipid, &temp_port1, &temp_port2, &seq, &ack_seq);
temp_seq = seq;
seq = ack_seq;
ack_seq = temp_seq;
ipid++;
break;
case '2':
printf("old ack is %x\n", ack_seq);
printf("pls input the seq plus amount: \n");
char amount[6];
gets(amount);
ack_seq= ack_seq+atoi(amount);
printf("new akc is %x\n", ack_seq);
send_ack(sd_raw, &svr_addr, lo_ipaddr, svr_ipaddr, htons(src_port), htons(dst_port), htons(ipid), htonl(seq), htonl(ack_seq));
ipid++;
break;
case '4':
send_rst(sd_raw, &svr_addr, lo_ipaddr, svr_ipaddr, htons(ipid), htons(src_port), htons(dst_port), htonl(seq), htonl(ack_seq));
break;
}
}
当我运行程序时,输出为:
old ack_seq is ab2429c6
pls input the seq plus amount:
new ack_seq is ab2429c6
sendto ack packet
:参数无效
BTW:send_ack
,send_rst
函数使用原始套接字发送数据包。
似乎gets()
函数没有被执行,这有什么问题?
谢谢!
答案 0 :(得分:1)
尝试检查返回值。如果在尝试读取字符时遇到文件结尾,则设置eof指示符(feof)。如果在读取任何字符之前发生这种情况,则返回的指针是空指针
兼容性 最新版本的C标准(2011年)最终将该功能从其规范中删除。 该函数在C ++中已弃用(截至2011年标准,遵循C99 + TC3)。
答案 1 :(得分:1)
在致电getchar();
之前致电gets
。就目前而言,您输入两个字符,即命令编号和换行符。因此gets
读取一个空行,剥离换行符,并在数组中存储一个空字符串。
正如其他答案中所述,gets
因其安全风险而被弃用,但这与您的问题无关。
答案 2 :(得分:0)
gets
首先,它不再是2011版标准的标准库的一部分(已在1999版本中弃用)。其次,将(不是,将)在您的代码中引入一个失败点/主要安全漏洞。自 80年代末以来,它一直是受欢迎的恶意软件漏洞。由一个图书馆功能引起的混乱比破坏40年的前景更可怕。遗留代码的价值,这就是两年前WG14最终从语言定义中删除它的原因。 那是它是多么邪恶。
改为使用fgets
:
fgets( data, sizeof data, stdin );
fgets
会将最多 sizeof data - 1
(在本例中为99)个字符存储到目标缓冲区,包括尾随换行符(如果有空间)。
您的问题是循环条件中的getchar
调用在您的输入后不会使用换行符。输入命令时,键入1 <Enter>
,因此输入流包含字符{'1', '\n'}
。在输入流中留下的换行信号表示后续gets
次呼叫的行尾,因此data
结束时基本上是空的。公平地说,这也是fgets
的一个问题;实际上,您可能希望在此实例中使用scanf
:
if ( scanf( " %99[^\n]", data ) == 1 )
{
...
}
格式字符串中的前导空格告诉scanf
跳过任何前导空格(例如从之前的scanf
或getchar
调用留下的换行符)并从第一个开始读取非空白字符。 %99[^\n]
转化说明符告诉scanf
最多可读取99个字符,或直到它看到换行符(或EOF)。
同样,您可能希望使用scanf
来读取命令代码,因此您可以忽略任何偏离的新行:
while ( scanf( " %c", &cmd ) == 1 ) // again, blank before %c causes any leading
{ // whitespace to be skipped
switch( cmd )
{
case '1':
char data[100];
if ( scanf( " %99[^\n]", data ) == 1 )
{
send_data( ... );
...
}
else
{
// handle input error
}
break;
...
}
}