-3

decrypted次のように配列に格納された文字列があります。

char decrypted[5000];
sprintf(decrypted,"%s","192.168.0.2<==>6060<==>this is ipsec data");

そして、次のようにsscanfを使用してこれを読み取ろうとしています:

char ip_source[20];
int port_source;
char message[1000];

 sscanf(decrypted,"%s<==>%d<==>%s",ip_source,&port_source,message);
 printf("source = %s\nport = %d\nmessage = %s\n",ip_source,port_source,message);

しかし、次の出力が得られるため、これは機能していないようです。

source = 192.168.0.2<==>6060<==>this
port = 0
message =

私は何を間違っていますか?どうすれば修正できますか?

編集:

以下の提案に従って、コードを変更した方法を次に示します。これが新しい出力です。

char decrypted[5000];
sprintf(decrypted,"%s","192.168.0.2<==>6060<==>this is ipsec data");

char ip_source[20];
int port_source;
char message[1000];

 sscanf(decrypted,"%[^<]<==>%d<==>%s",ip_source,&port_source,message);

 printf("source = %s\nport = %d\nmessage = %s\n",ip_source,port_source,message); 

出力:

source = 192.168.0.2
port = 6060
message = this

メッセージを完全な文字列として読み取らせ、最初のスペースで止まらないようにするにはどうすればよいですか?

編集2:

善良な皆さん、もう少しだけお楽しみいただけますか?

ここに私が読もうとしている別の文字列があります:

sprintf(decrypted,"%s","S=192.168.0.2|D=192.168.0.4||<==>S=6060");
sscanf(decrypted,"S=%s|D=%s||<==>S=%d",&ip_source,&ip_dest,&port_source);

再び問題を引き起こしています。次のように解決策を修正しようとしました。

sscanf(decrypted,"S=%[^<]<==>|D=%s||<==>S=%d",&ip_source,&ip_dest,&port_source);

しかし、それはうまくいきませんでした。それを修正するために上記を変更するにはどうすればよいですか?

4

2 に答える 2

4

問題は、最初の%sユーザーがどこで停止するかわからないことです。に置き換え%[^<]て修正します。

もう 1 つの問題は、message文字列が早期に終了することです。メッセージ内で許可されていない文字 (たとえば、\n) を選択%[^\n]し、メッセージを読むために使用します。

最後に、固定バッファーに読み込んでいるので、標準的な予防措置を適用して、sscanfバッファーの大きさを伝えます。

sscanf(decrypted, "%19[^<]<==>%d<==>%999[^\n]", ip_source, &port_source, message);

ideone のデモ

通常、文字列に固定の delimiter がある場合は、xその区切り文字を%[^x]書式指定子で使用します。したがって、"S=%s|D=%s||<==>S=%d"フォーマット文字列は次のようになります"S=%19[^|]|D=%19[^|]||<==>S=%d"

于 2013-10-15T09:15:32.250 に答える
2
sscanf(decrypted,"%s<==>%d<==>%s",ip_source,&port_source,message);

ではscanf%sデフォルトでスペースと見なされないすべての文字を消費します。それがあなたが入る理由192.168.0.2<==>6060<==>thisですsource

scanf次のように区切り文字と見なされるものを変更することで、これを修正できます。

sscanf(decrypted,"%[^<]<==>%d<==>%s",ip_source,&port_source,message);

編集:

に格納されるものにも同じ規則が適用されmessageます。、 、およびスペースmessageのセットにのみ文字を含めることができると仮定すると、これを試してみることができます。a-zA-Z

sscanf(decrypted,"%[^<]<==>%d<==>%[A-Za-z ]",ip_source,&port_source,message);

EDIT2:

[^<]他の文字列については、今回は区切り文字が であるため、使用できません|。代わりにこれを使用する必要があります。

sscanf(decrypted,"S=%[^|]|D=%[^|]||<==>S=%d",ip_source,ip_dest,&port_source);

また、&ip_sourceand&ip_destは文字配列として定義されているため、間違っている可能性があります。参照演算子は必要ありません。

最後に、他の回答に記載されているように、 buffer に制限チェックを追加することを検討してください。

sscanf(decrypted,"%19[^<]<==>%d<==>%999[a-z]",ip_source,&port_source,message);

同じことが 2 番目の にも当てはまりscanfます。

于 2013-10-15T09:16:40.853 に答える