简体   繁体   中英

gets() doesn't get excuted

in my source codes, there is the following snippet:

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

when I run the program, the output is:

old ack_seq is ab2429c6
pls input the seq plus amount: 
new ack_seq is ab2429c6
sendto ack packet

: Invalid argument

BTW: the send_ack , send_rst functions use raw socket to send packets. it seems that the gets() function doesn't get excuted, what is wrong with this? thanks!

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

Call getchar(); before you call gets . As it stands, you input two characters, the command number and a newline. So gets reads a blank line, strips the newline, and stores an empty string in your array.

As noted in the other answers, gets is deprecated because of its security risk, but this doesn't relate to your problem.

First of all, it is no longer part of the standard library as of the 2011 version of the standard (having been deprecated in the 1999 version). Secondly, it will (not may, will ) introduce a point of failure / major security hole in your code. It has been a favored malware exploit since the late 1980s . The mayhem caused by that one library function was scarier than the prospect of breaking 40 years' worth of legacy code, which is why WG14 finally removed it from the language definition two years ago. That's how evil it is.

Use fgets instead:

fgets( data, sizeof data, stdin );

fgets will store at most sizeof data - 1 (in this case, 99) characters to the target buffer, including the trailing newline character if there's room.

Your problem is that the getchar call in the loop condition doesn't consume the newline following your input. When you enter a command, you type 1 <Enter> , so the input stream contains the characters {'1', '\\n'} . That newline that's left in the input stream signals an end-of-line to the following gets call, so data winds up being essentially empty. To be fair, this is a problem for fgets as well; you may actually want to use scanf in this instance:

if ( scanf( " %99[^\n]", data ) == 1 )
{
  ...
}

The leading blank space in the format string tells scanf to skip any leading whitespace (such as newlines left over from a previous scanf or getchar call) and start reading from the first non-whitespace character. the %99[^\\n] conversion specifier tells scanf to read up to 99 characters, or until it sees a newline character (or EOF).

Similarly, you may want to use scanf to read the command codes, so you can ignore any stray newlines:

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;
      ...
  }
}    

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM