0

在我的源代码中,有以下代码段:

    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

: 无效的论点

顺便说一句:send_ack,send_rst函数使用原始套接字发送数据包。似乎该gets()功能没有被执行,这有什么问题?谢谢!

4

3 回答 3

1

Try checking the return value..If the end-of-file is encountered while attempting to read a character, the eof indicator is set (feof). If this happens before any characters could be read, the pointer returned is a null pointer

Compatibility The most recent revision of the C standard (2011) has definitively removed this function from its specification. The function is deprecated in C++ (as of 2011 standard, which follows C99+TC3).

于 2013-03-25T10:39:13.627 回答
1

打电话getchar();之前先打电话gets。就目前而言,您输入两个字符,命令号和换行符。所以gets读取一个空行,去掉换行符,然后在你的数组中存储一个空字符串。

正如其他答案中所述,gets由于其安全风险而被弃用,但这与您的问题无关。

于 2013-03-25T10:41:59.057 回答
0

从来没有 从来没有 从来没有 从来没有使用gets

首先,从 2011 版标准开始,它不再是标准库的一部分(在 1999 版中已弃用)。其次,它将不是可能,)在您的代码中引入故障点/主要安全漏洞。自1980 年代后期以来,它一直是一种受欢迎的恶意软件利用。一个库函数造成的混乱比破坏 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跳过任何前导空格(例如从前一个scanfgetchar调用留下的换行符)并从第一个非空格字符开始读取。%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;
      ...
  }
}    
于 2013-03-25T15:35:27.800 回答