obtiene () no se excuye

en mis códigos de origen, hay el siguiente fragmento de código:

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

Cuando ejecuto el progtwig, la salida es:

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

: Argumento no válido

Por cierto: las funciones send_ack , send_rst usan socket sin procesar para enviar paquetes. Parece que la función gets() no se excuye, ¿qué hay de malo en esto? ¡Gracias!

Llamar a getchar(); antes de llamar se gets Tal como está, ingresa dos caracteres, el número de comando y una nueva línea. Entonces lee una línea en blanco, elimina la nueva línea y almacena una cadena vacía en su matriz.

Como se señaló en las otras respuestas, gets está en desuso debido a su riesgo de seguridad, pero esto no se relaciona con su problema.

Intente verificar el valor de retorno … Si se encuentra el final del archivo al intentar leer un carácter, el indicador eof se establece (feof). Si esto sucede antes de que se pueda leer cualquier carácter, el puntero devuelto es un puntero nulo

Compatibilidad La revisión más reciente del estándar C (2011) ha eliminado definitivamente esta función de su especificación. La función está en desuso en C ++ (a partir del estándar de 2011, que sigue a C99 + TC3).

NUNCA NUNCA NUNCA NUNCA NUNCA NUNCA USAR

En primer lugar, ya no forma parte de la biblioteca estándar a partir de la versión 2011 del estándar (que ha quedado en desuso en la versión 1999). En segundo lugar, (no podrá) introducirá un punto de falla / mayor agujero de seguridad en su código. Ha sido una explotación maliciosa favorecida desde fines de los años ochenta . El caos causado por esa función de biblioteca fue más aterrador que la posibilidad de romper el código heredado de 40 años, razón por la cual WG14 finalmente lo eliminó de la definición de lenguaje hace dos años. Así de malvado es.

Use fgets lugar:

 fgets( data, sizeof data, stdin ); 

fgets almacenará a lo máximo sizeof data - 1 (en este caso, 99) caracteres en el búfer de destino, incluido el carácter de nueva línea final si hay espacio.

Su problema es que la llamada getchar en la condición de bucle no consume la nueva línea después de su entrada. Cuando ingresa un comando, escribe 1 , de modo que el flujo de entrada contiene los caracteres {'1', '\n'} . Esa nueva línea que queda en el flujo de entrada señala un final de línea para la siguiente llamada de llamada, por lo que los data terminan prácticamente vacíos. Para ser justos, este también es un problema para los fgets ; es posible que desee utilizar scanf en esta instancia:

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

El espacio en blanco inicial en la cadena de formato le dice a scanf que se salte cualquier espacio en blanco inicial (como las líneas nuevas que quedaron de una llamada anterior a scanf o getchar ) y que comience a leer desde el primer carácter que no sea espacio en blanco. el especificador de conversión %99[^\n] le dice a scanf que lea hasta 99 caracteres, o hasta que vea un carácter de nueva línea (o EOF).

Del mismo modo, es posible que desee utilizar scanf para leer los códigos de comando, para que pueda ignorar cualquier nueva línea extraviada:

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