'/'
入力は、次のように、で区切られた文字列と整数で構成されます。
hello/17
そして、次のように、入力を文字列とに読み取りたいと思いますint
。
char str[20];
int num;
scanf("%s/%d", str, &num); // this how I tried to do it.
うまくいかないようです、何かアドバイスはありますか?
scanf
を読み込もうとすると、空白で終了する文字列を待ちます%s
。
禁止されている文字セットを直接指定してみてください。
scanf("%19[^/]/%d", str, &num);
フォーマットコードについて詳しくは、こちらをご覧ください。
次のプログラムを実行するだけで済みます。
#include <stdio.h>
int main (void) {
char str[20] = {'\0'};
int count, num = 42;
count = sscanf ("hello/17", "%s/%d", str, &num);
printf ("String was '%s'\n", str);
printf ("Number was %d\n", num);
printf ("Count was %d\n", count);
return 0;
}
なぜこれが起こっているのかを見るために。出力は次のとおりです。
String was 'hello/17'
Number was 42
Count was 1
その理由は、%s
フォーマット指定子に関係しています。C99から7.19.6.2 The fscanf function
(C11ではほとんど変更されておらず、斜体は私のものです):
s
:空白以外の文字のシーケンスに一致します。
/
は空白ではないため、同じ理由でと同様に文字列ビットに含まれます17
。sscanf
これは、が返されるという事実によっても示されます。これは、 1つのアイテムのみがスキャンされたことを1
意味します。
次に探しているのは、文字列以外の/
文字(空白を含む)をスキャンするものです。標準の同じセクションもそこに役立ちます:
[
:予想される文字のセット(スキャンセット)からの空でない文字のシーケンスに一致します。変換指定子には、一致する右角かっこ(])までの、フォーマット文字列内の後続のすべての文字が含まれます。左角かっこの後の文字が曲折アクセント記号(^)でない限り、角かっこ(スキャンリスト)の間の文字がスキャンセットを構成します。この場合、スキャンセットには、曲折アクセント記号と右角かっこの間のスキャンリストに表示されないすべての文字が含まれます。
言い換えれば、次のようなものです。
#include <stdio.h>
int main (void) {
char str[20] = {'\0'};
int count, num = 42;
count = sscanf ("hello/17", "%[^/]/%d", str, &num);
printf ("String was '%s'\n", str);
printf ("Number was %d\n", num);
printf ("Count was %d\n", count);
return 0;
}
それはあなたに与えます:
String was 'hello'
Number was 17
Count was 2
もう1つのアドバイス:無制限または;で使用scanf
しないでください。あなたはバッファオーバーフロー攻撃を求めています。堅牢なユーザー入力機能が必要な場合は、この回答を参照してください。%s
%[
文字列として入力すると、sscanf
バッファオーバーフローを気にすることなく、心ゆくまでそれを実行できます(入力のサイズを制限しているため)。
そのようになる可能性があります:
char str[20];
int num;
scanf("%19[^/]%*c%d", str, &num);
%*c
1文字を読み取り、それを破棄します