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_acksend_rst関数はrawソケットを使用してパケットを送信します。gets()関数が実行されないようですが、これの何が問題になっていますか?ありがとう!

4

3 に答える 3

1

戻り値を確認してみてください。文字の読み取り中にファイルの終わりが検出されると、eofインジケーターが設定されます(feof)。文字を読み取る前にこれが発生した場合、返されるポインタはnullポインタです

互換性C標準の最新のリビジョン(2011)は、この関数を仕様から完全に削除しました。この関数はC++で非推奨になりました(2011年の標準では、C99 + TC3に準拠しています)。

于 2013-03-25T10:39:13.627 に答える
1

電話をかけるgetchar();前に電話してくださいgets。現状では、コマンド番号と改行の2文字を入力します。したがってgets、空白行を読み取り、改行を取り除き、空の文字列を配列に格納します。

他の回答で述べたように、getsセキュリティリスクのために非推奨になりましたが、これは問題とは関係ありません。

于 2013-03-25T10:41:59.057 に答える
0

決して決して決して決して決して決して使用しないgets

まず第一に、2011バージョンの標準(1999バージョンでは非推奨)の時点で、標準ライブラリの一部ではなくなりました。第二に、それはあなたのコードに単一障害点/主要なセキュリティホールを導入します(そうではないかもしれません) 。1980年代後半から、マルウェアのエクスプロイトとして好まれてきました。その1つのライブラリ関数によって引き起こされた騒乱は、40年分のレガシーコードを壊すという見通しよりも恐ろしいものでした。そのため、WG14は2年前に最終的にそれを言語定義から削除しました。 それはそれがどれほど邪悪であるかです。

fgets代わりに使用してください:

fgets( data, sizeof data, stdin );

fgets最大 (この場合は99)文字をターゲットバッファに格納sizeof data - 1します。これには、スペースがある場合は末尾の改行文字も含まれます。

問題は、ループ状態の呼び出しが入力に続く改行を消費しないことですgetcharコマンドを入力するときに入力すると1 <Enter>、入力ストリームに文字が含まれます{'1', '\n'}。入力ストリームに残っているその改行は、次のgets呼び出しへの行の終わりを通知するため、data本質的に空になります。公平を期すために、これはfgets同様に問題です。この場合、実際に使用することをお勧めしscanfます。

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

フォーマット文字列の先頭の空白は、先頭の空白(前の文字や呼び出しscanfから残った改行など)をスキップして、最初の非空白文字から読み取りを開始するように指示します。変換指定子は、最大99文字を読み取るように、または改行文字(またはEOF)が表示されるまで読み取るように指示します。 scanfgetchar%99[^\n]scanf

同様に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 に答える