人に聞けない痔の悩み、これでスッキリ >>

プログラムで、
A~Cの記号が選ばれるまで、
(つまり他の文字が入力されたらもう一度入力しなすようにしたい)
入力コマンドを繰り返す制御文を作りたいのですが
自分で作ってもうまくいきません。

char c;
while((c=getchar())!='A'||'B'||'C'){
}
以下はA,B,Cのいずれかが入力されたら実行される制御文が続く


しかし、実際はA~Cを入力しても、
次の制御文に移りません。
どこがおかしいでしょうか?
また、正しく動かすにはどうすればよいでしょうか?

このQ&Aに関連する最新のQ&A

A 回答 (5件)

試してないけどこのコードは無限ループでしょうね。


人間の考え方と、コンピュータの考え方の違いがまさに現れてるコードに見える。

このコードは簡単に言うと、while(判定文1or判定文2or判定文3)てことです(それはわかりますか?)。

で、判定文1は今仮に置いとくとしても、判定文2と判定文3は絶対にTrueになってしまうんですよ。

それはわかりますか?
判定文というのは、要は0ならFalse、0以外ならTrueですから、判定文2に'B'という0以外の値('B'は0x42)を書いた時点で必ずTrueになってしまいます。

だから、たとえ判定文1がFalseであっても判定文2は絶対Trueになるから、判定文3は評価されることすらなく、while()の中全体の評価は必ずTrueとなってしまい、無限ループになります(次の制御文に行きません)。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
while((c=getchar())!='A'||'B'||'C')
ここが変だと気づきました。
へぼミスです。
親切な回答ありがとうございました。

お礼日時:2007/12/18 12:22

無限ループになる理由はNo4さんが回答しているので、


蛇足ですが、一度は必ず入力するならば、
int c;
do{
 c = getchar();
}while( c!='A' && c!='B' && c!='C' );
でいいかと。

親切なのはNo1さんのが親切かな。

ちなみに細かいですが、getcharは入力ストリームから文字を、
unsigned char型の値として読み取り、int型に変換して返してきます。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
間違えていた箇所がわかりました。
ありがとうございました。

お礼日時:2007/12/18 12:10

対称性が崩れてるからヤダ。

    • good
    • 0
この回答へのお礼

意味がわかないのですが

お礼日時:2007/12/18 12:22

 ちょっとすっきり。


while ( (c = getchar()) != 'A' && c != 'B' && c != 'C' ) {
  fprintf(stderr, "re-enter a character\n");
}
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
そうですね^^

お礼日時:2007/12/18 12:23

>どこがおかしいでしょうか?


明らかに

(c=getchar())!='A'||'B'||'C'

ですね。

char c = getchar();
while ( c != 'A' && c != 'B' && c != 'C' ) {
  fprintf(stderr, "re-enter a character\n");
  c = getchar();
}

という風か?
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
間違っていた箇所がわかりました。

お礼日時:2007/12/18 12:23

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QEnterキーを押されたら次の処理に移るという事をしたい。

コンソールアプリケーション上で文字列を表示させた後、ユーザーがエンターキーを押したら次の文字列を表示するという仕様にしたいのですが、エンターキーだけ入力待ちにするっていうのはどのように書けばいいんでしょうか?

Aベストアンサー

#include <stdio.h>

int main(void)
{
char *str[] = {"abc", "def", "ghi", "jkl"};
int i;

for(i = 0; i < 4; i ++){
while(getchar() != '\n') ;
puts(str[i]);
}
return 0;
}

Q*をユーザーが入力した数字の数だけ表示するプログラムの作り方を教えてください

はじめまして。
現在C言語の勉強している大学生です。

『*』をユーザーが入力した数字の数だけ表示するプログラムの作り方を教えてください。
例えばユーザーが5と入力したら*****とでるもの。

(本に載っている演習なのですが答えがのっていないのです。)
whileかforを使うのだと思うんですが。。
よろしくお願い致します。

Aベストアンサー

これで、OKです。
とても簡単なプログラムです。

#include<stdio.h>
int main(void)
{
int i,num;
printf("何個表示しますか?->");scanf("%d",&num);

for(i=0;i<num;i++)
{
printf("*");
}
printf("\n");

return 0;
}

QC言語 While文(ループ)内の文字入力

While文で、1文字入力をやれば思うようにうまくいかない。数字(データ)入力や、文字列入力の場合(%d 及び %s)ならうまくいく。文面で説明するより実際のプログラムを見た方が分かりやすいと思うので、以下にプログラムとその実行結果、実行結果に対する私が意図している結果とを示します。

【プログラム部分】
#include<stdio.h>

int main(void)
{
   char a;

   while(1)
   {
   printf("1文字を入力:");
   scanf("%c",&a);

   if(a == 'x')
     break;

   printf("入力したのは %c です。\n",a);
   }

   return 0;
}

【実行結果(キーボードからは「 e 」と入力」)】
1文字を入力:e
入力したのは e です。
1文字を入力:入力したのは
です。
1文字を入力:

【私が意図している結果】
1文字を入力:e
入力したのは e です。
1文字を入力:


 ちなみにC言語の環境は、インターネットで無料で入手できる試食版です。(LSI C-86 Ver3.30c 試食版)
 上記プログラムを見てもらえればお分かりだと思いますが、「xを入力するまで、永遠と1文字入力とその表示を行う」ことを意図しています。しかし実際の結果は意図に反しています。
 1回目は正常に動作しているようですが、問題は2回目以降。scnafで入力待ちをすることなく、なぜかscanfをスルーする形で3回目のscanf入力待ちとなっています。この理由を教えてください。お願いします。

While文で、1文字入力をやれば思うようにうまくいかない。数字(データ)入力や、文字列入力の場合(%d 及び %s)ならうまくいく。文面で説明するより実際のプログラムを見た方が分かりやすいと思うので、以下にプログラムとその実行結果、実行結果に対する私が意図している結果とを示します。

【プログラム部分】
#include<stdio.h>

int main(void)
{
   char a;

   while(1)
   {
   printf("1文字を入力:");
   scanf("%c",&a);

   if(a == ...続きを読む

Aベストアンサー

>1文字を入力:入力したのは
>です。

は、[Enter]キーの入力によるためです。
[Enter]キーをスルーする必要があります。

   char a;
char dummy; /*[Enter]キー用*/

   while(1)
   {
   printf("1文字を入力:");
   scanf("%c",&a);
scanf("%c",&dummy); /*[Enter]キー用*/

   if(a == 'x')
     break;

   printf("入力したのは %c です。\n",a);
   }


で、どうでしょうか?

Qsleep()関数について

"数秒おきに警報をn回鳴らすプログラム"をC言語で作成しようと
考えています。

プログラム実行環境はWindowsですが、
sleep()関数は使用できないのでしょうか??

仮に使用できない場合、この関数に代わる関数や代替方法が
あれば教えて頂けませんでしょうか? 宜しくお願いします。

Aベストアンサー

正確な動作でも構わなければ
windows.hをインクルードして
Sleep()関数を使いましょう.
http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200207/02070061.txt

しかし,正確に数秒おきに動作を行いたい場合はマルチメディアタイマ等を使いましょう.
マルチメディアタイマはミリ秒間隔でコールバック関数を呼び出すことができます.
timeSetEventを用いてコールバック関数の登録を行うことができます.
timeKillEventでコールバック関数の解除を行うことができます.

多分他にも方法があると思うのですが…私はこれぐらいしか知りません^^;

参考URL:http://www.katto.comm.waseda.ac.jp/~katto/Class/GazoTokuron/code/time.html


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング

おすすめ情報