2013-03-25 3 views
0

в моих исходников, есть следующий фрагмент:получает() не получает excuted

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

Вы проверили на '' ack_seq' после получает() '? –

+0

Каково значение 'amount' после' gets() '? – Dipto

+0

Я изменил источник и вывод – user1944267

ответ

1

Звоните getchar(); прежде чем позвонить по телефону gets. Как бы то ни было, вы вводите два символа, номер команды и новую строку. Итак, gets читает пустую строку, разделяет строку новой строки и сохраняет пустую строку в вашем массиве.

Как указано в других ответах, gets устарел из-за его угрозы безопасности, но это не относится к вашей проблеме.

1

Попробуйте проверить возвращаемое значение. Если при попытке прочитать символ встречается конец файла, устанавливается индикатор eof (feof). Если это происходит до того, как любые символы могут быть прочитаны, возвращаемый указатель является нулевым указателем

Совместимость Последняя редакция стандарта C (2011) окончательно удалила эту функцию из ее спецификации. Функция устарела в C++ (по состоянию на 2011 год, которая следует за C99 + TC3).

+0

вы можете сделать его более понятным? Я не понимаю – user1944267

+0

Pls пытается проверить возвращаемое значение получает .. – hazzelnuttie

0

НИКОГДА НИКОГДА НИКОГДА НИКОГДА НЕ НИКОГДА USE gets

Прежде всего, это уже не входит в стандартную библиотеку в версии стандарта 2011 года (будучи устаревшей в версии 1999 года) , Во-вторых, это будет (не может, будет) ввести точку отказа/главное отверстие безопасности в вашем коде. Это был популярный вредоносный код с конца 1980-х годов. Погром, вызванный этой библиотечной функцией, был страшнее, чем перспектива нарушения устаревшего кода на 40 лет, поэтому WG14, наконец, удалил его из определения языка два года назад. Это как зло.

Использование fgets вместо:

fgets(data, sizeof data, stdin); 

fgets будет хранить в самыхsizeof data - 1 (в данном случае 99) символов в целевой буфер, в том числе задней символом новой строки, если есть место.

Задача заключается в том, что вызов в состоянии цикла не потребляет новую строку после ввода. Когда вы вводите команду, вы вводите 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; 
     ... 
    } 
}  
Смежные вопросы