getchar を while ループの条件として使用し、(c=getchar()) = EOF または '\n' または '\0' の場合に終了させる方法。
私は試した:
int c=0;
while((c=getchar()) != EOF || '\n' || '\0'){
putchar();
}
入力した場合: WEATHER(+enter)。ループを終了しませんでした。
どうすればこれを機能させることができますか?
教えて
getchar を while ループの条件として使用し、(c=getchar()) = EOF または '\n' または '\0' の場合に終了させる方法。
私は試した:
int c=0;
while((c=getchar()) != EOF || '\n' || '\0'){
putchar();
}
入力した場合: WEATHER(+enter)。ループを終了しませんでした。
どうすればこれを機能させることができますか?
教えて
次のようなものを使用できます。
int c = 0;
while((c=getchar()) != EOF) {
if ((c == 0) || (c == '\n'))
break;
putchar(c);
}
while ((c = getchar()) != EOF && c != '\n' && c != '\0')
{
// loop body
}
これが機能するのは、&&
演算子 a) は常に最初に LHS 式を評価し、b) シーケンス ポイントを導入するため、LHS 式の副作用 ( to の結果を代入するなどgetchar
)c
は、RHS 式が評価される前に適用されるためです。
私はこれがうまくいくと思います:
int c;
while( (c=getchar()) != EOF && c!='\n' && c!='\0') {
putchar();
}
ただし、次のようにする方がよい場合があります。
int c=getchar();
while( c != EOF && c!='\n' && c!='\0'){
putchar();
c=getchar();
}
残念ながら、それを複数のステートメントに分解する必要があります。複数の論理和を実行しようとしていて、「真」が「ゼロ以外のすべて」であり、文字が単なる数字であり、そのほとんどがゼロでない場合、基本的に「c は EOF ではありませんが、またはTRUEまたはTRUE」。
C の仕様については完全にはわかりませんが、ステートメントを次のように書き直すとうまくいくかもしれません。
while((c=getchar()) != EOF && c!='\n' && c!='\0')
これは、評価の順序に基づいて定義されていない可能性があり、乱雑に見えます。
より良い解決策は、"c=getchar()" を別の場所に移動し、代わりに while ヘッダーで C の値を確認することです。これは、「c=getchar()」をループの外側と while ループ本体の下部の両方に移動する必要があることを意味します。
コードを因数分解します。
while (intint((int []){ EOF, '\n', 0 }, c=getchar(), 3) ...
intint
あなたが書いた関数はどこにありますmemchr
が、intの配列を取ります。:-)
他の回答は問題を十分に解決しているため、この回答は半分冗談ですが、ポイントは、多くの場合、適切なインターフェイスで適切な関数を定義すると、コードがはるかに単純になるということです。
EOF || '\n' || '\0'
は常に評価されるブール式であるtrue
ため、条件は に要約されるため、機能しませんif( c != true )
。これは、c が nul の場合のみでtrue
あり、getchar() は通常は返されません。
条件での代入は常に不適切であり、一部のコンパイラは、代入自体が括弧で囲まれていない限り、警告を発行します。=
これは、より一般的==
な状態が意図されていた場所を誤って使用しないように警告するためです。
C では、それぞれが同じ変数をテストする場合でも、個別のブール式が必要です。
int c = getchar() ;
if( c != EOF && c != '\n' && c != '\0' )
...
非常に大規模ですが、非常に個別のソリューションは次のとおりです。
#include <stdarg.h>
#define END_INPUT -12332 // not likely to be returned from getchar()...
int is_any(int c, ...)
{
va_list ap;
va_start(ap, c);
int ret = 0;
while (ret == 0) {
int a = va_arg(ap, int);
if (a == END_INPUT) break; // End of inputs - not any of the given ones
if (c == a) ret = 1; // will result in a break as well...
}
va_end(ap);
return ret;
}
int main()
{
int c;
while( isany(c=getchar(), EOF, '\n', '\0', END_INPUT) {
...
}
}
を放棄して代わりにint c
使用するchar
場合は、「除外リスト」を拡張可能に保ちながら、標準ライブラリ関数を使用して短くコーディングできます。
char terminate_on[] = { EOF, '\n', '\0' }; /* needs to end with '\0' */
char c[2] = { '\0', '\0' };
while ((*c = getchar()) && !strpbrk(c, terminate_on))
putchar(*c);
たった 2 つの "break" 文字の場合でも、明示的なテスト シーケンスよりも効率が悪い可能性があります。
strpbrk()
その機能が何をするかを見てください。