scanf("%[^\n]s",str1);
scanf("%[^\n]s",str2);
私は複数のアレイのためにそれを使用する場合、そのが機能していない。 いずれかがあります私の側からのミスか、我々は複数の配列のためにそれを使用傾ける我々はscanf関数( "%の[^ nを]よ、STR)を使用することはできますか?
scanf("%[^\n]s",str1);
scanf("%[^\n]s",str2);
私は複数のアレイのためにそれを使用する場合、そのが機能していない。 いずれかがあります私の側からのミスか、我々は複数の配列のためにそれを使用傾ける我々はscanf関数( "%の[^ nを]よ、STR)を使用することはできますか?
をそれが可能だ:?
scanf(" %[^\n]",str1);
scanf(" %[^\n]",str2);
注意力scanf()
は先頭の空白をスキップすることを前のスペース、(最初に読み取らいない改行呼び出し回数は空白文字として)
しかし:このコードは可能未定義の動作を持っている入力は長くお使いstr1
やstr2
缶店よりもラインを持っている場合、それは、バッファオーバーフローが発生します。 あなたはそのようなコードを書かないでください。 scanf()
で
、あなたは文字の量を制限するフィールド幅を使用することができます読み:fgets()
:
str1[256];
scanf(" %255[^\n]", str1); // one less because a 0 character must be appended
をはるかに良いラインを読み取るジョブ専用の機能を使用することです:あなたが説明するようにscanf()
を呼び出す
#include <stdio.h> // for fgets()
#include <string.h> // for strcspn()
#define BUFFERSIZE 256
// [...]
str1[BUFFERSIZE];
int main(void)
{
// [...]
// no need to subtract 1 here, `fgets()` accounts for the trailing `0`:
if (!fgets(str1, BUFFERSIZE, stdin))
{
// read error, e.g. print error message
exit(1);
}
// fgets includes the newline if there was one, so strip it:
str1[strcspn(str1, "\n")] = 0;
// [...]
}
しかし、提案された 'scanf()'形式は、その行が空白で始まる場合は、最初の行に対してOPとは異なる結果をもたらします。また、その行が空白で始まる場合は、2番目の行に期待されるOPとは異なる結果を生成します。 –
完全性のためだけに、私はこのタスクのために 'scanf()'を提案しません。 –
...
scanf("%[^\n]s",str1);
はなく、最初の改行を含めないまで、行頭の空白をスキップない、str1
によって指定された文字配列に標準入力から文字を読み込みます。 改行がある場合は、未読のままです。配列にゼロ文字が転送されると、一致するエラーが発生します(したがって、文字列ターミネータには依存しません)。それ以外の場合、scanf()
は's'
文字の読み取り(および無視)を試みますが、常に一致するエラーが発生する必要があります。キャラクターは消費されません。
%[
ディレクティブとの一致を試みると必然的に一致するエラーが発生した場合は0を返し、 "s"と一致する場合は1を返します。ゼロ文字が標準入力から読み取られたままの場合、またはI/Oエラーが発生した場合は、EOF
が返されます。
直ちに同じフォーマットで再度読もうとすると、%[
ディレクティブで2回目の読み込みに常に入力エラーまたは一致するエラーが発生する必要があります。これ以上の文字がある場合は、改行してください。
通常、行単位で読むことは、fgets()
で行われる方がよくなります。でも中に満たされた詳細の一部なしに、かなり長いですので、私は、独自の関数にそれを考慮するためにあなたをお勧めする
char str1[100];
char c;
int result;
// Note use of a field width to protect from buffer overrun:
result = scanf("%99[^\n]%c", str1, &c);
switch (result) {
case EOF: /* no characters available or I/O error */
/* ... handle error ... */
break;
case 0:
/* the first character was a newline */
result = getchar(); // consume the newline
assert(result == '\n');
str1[0] = '\0'; // ensure the (empty) string is terminated
break;
case 1:
/* should happen only at end of file or on I/O error */
assert(feof(stdin) || ferror(stdin));
/* ... any special handling for this being the last line of the file ... */
break;
case 2:
if (c != `\n`) {
/* the line was longer than 99 characters (excluding the newline) */
/* ... recover from overlength line ... */
}
break;
default:
/* should never happen */
/* ... handle unexpected result ... */
}
:あなたはscanf()
経由でそれを行う必要があるなら、あなたはこれらの線に沿って何かを行う必要があります。また、fgets()
は簡略化していることに注意してください。erでも、まだ複雑です。特に、余分な長さの行を注意する必要があります。fgets()
には、文字列の末尾に改行があります(ある場合)。
'%[^ \ n] s'は間違っています。* [*] *または*' s'のどちらかを使用してください。 '%[]'は 'scanf()'の落とし穴の一つである最初の空白をスキップしません。私の[scanf() 'から離れた私の[初心者用ガイド](http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html)を見てください。 –