gets()没有被执行

时间:2013-03-25 10:29:33

标签: c

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

    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_acksend_rst函数使用原始套接字发送数据包。  似乎gets()函数没有被执行,这有什么问题? 谢谢!

3 个答案:

答案 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跳过任何前导空格(例如从之前的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;
      ...
  }
}