ここから質問投稿すると、最大4000ポイント当たる!!!! >>

#include <stdio.h>

int main(void)
{
char str[255];
int i, len;

while (1){
printf("文字列を入力してください:");

if (fgets(str, sizeof(str), stdin) == NULL) {
break;
}
len = strlen(str);
if (len > 0 && str[len - 1] == '\n') str[len - 1] = '\0';

if (str[0] == '\0') break;

enterで終了するプログラムの例ですが、
if (fgets(str, sizeof(str), stdin) == NULL)
のNULLはどういった理由で必要ですか?
また、
if (len > 0 && str[len - 1] == '\n') str[len - 1] = '\0';
を消して、
if (str[0] == '\0') break;
を、if (str[0] == '\n') break;
と書き換えれば、終了すのではないですか?不適な理由がありますか?

A 回答 (2件)

>if (fgets(str, sizeof(str), stdin) == NULL)


>のNULLはどういった理由で必要ですか?
入力時に何らかのエラーを起こす場合があります。
例えば、stdin は、他のファイルからの入力にリダイレクトされている場合があります。
その時にファイルが(デバイスの都合で)読めなかったり、ファイルが終端に達していて読込が継続できない場合があります。
(標準入力からCTRL+Zが入力される場合と同じ)
>if (str[0] == '\n') break;
>と書き換えれば、終了すのではないですか?不適な理由がありますか?
特別不適な理由はありません。
そのような仕様であるとすることができると思います。
ただ、場合によっては、\r\nの場合を考える必要がある(予防措置)のだったり、
本処理に入る前に\nの処理をしておきたいというのかもしれません。
    • good
    • 0

Cでは、文字列の終端をNULLにしないと、終端を判別できません。

    • good
    • 0

お探しの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;
}

QC++で空Enterの入力を判断したい!!

空エンターで制御したい処理があるのですが、
char in[128];
gets(in);

if(in[0]=='n')
↑の判定だとif文に中に入ってくれません。
入力なしでもOKな様にgetsを使ってみました。
(ちなみにこのinには値が入ることもあります。)
enterの入力は改行コードが入るわけではないのでしょうか?
その場合どのように判定すればいいのか教えてください!
お願いします!!

Aベストアンサー

ランタイムライブラリの仕様を確認しましょう

VC++ですと getsで入力された文字列は最初の改行文字'\n'までがバッファに格納され '\n'を NULL文字の'\0'に変換する
となっているようです

判定の方法として

gets( buf );
if ( buf[0] == '\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);
   }


で、どうでしょうか?

Qダメだ・・・分からない。while文 無限ループ&’\n’エンター後無限ループ脱出

忙しい中失礼します。
C言語超初心者のものです。while文での表示について質問があります。
下記の’プログラム内容’はEnterキーが押されるまで、
’k’入力後 → Enterキー → ASCII value of k is 107. 
’t’入力後 → Enterキー → ASCII value of t is 116.
・・・
のように継続させ、
何もアルファベットを記入せず、’Enterキー’のみを押した場合はループから抜け、DOS画面を終了するようにしたいのですが、それが出来ません・・・。

’k’入力後Enterキーを押すと、’Enter a character:’の表示がなされた後、’Press any key to continue・・・’となり画面を閉じなければいけなくなります。
while文の中の()内を何とかすれば、思い通りのプログラムになる、とは思うのですが、それが考え付きません。
申し訳ありませんが、よろしければそのヒントを下さい。多分すごく簡単なことだとは思うのですが、それが出来ません。

※私個人の考えとしては、while文の中の(scanf("%c", &ch)&&(ch!='\n'))において、’&&(ch!='\n')’をプログラム文からなくせば、Enterキーを押さない限り(’k’入力後のEnterキー除く)、何度もパソコン側から尋ねられると思ったのですが・・・。・・・うまくいかず。

プログラミング内容:
#include <stdio.h>
#include <stdlib.h>

int main()
{
char ch;
printf("Enter a character:\n");

while(scanf("%c", &ch)&&(ch!='\n'))
{
printf("ASCII value of %c is %d.\n\n", ch, ch);

printf("Enter a character:\n");
}

system("PAUSE");
return 0;
}

忙しい中失礼します。
C言語超初心者のものです。while文での表示について質問があります。
下記の’プログラム内容’はEnterキーが押されるまで、
’k’入力後 → Enterキー → ASCII value of k is 107. 
’t’入力後 → Enterキー → ASCII value of t is 116.
・・・
のように継続させ、
何もアルファベットを記入せず、’Enterキー’のみを押した場合はループから抜け、DOS画面を終了するようにしたいのですが、それが出来ません・・・。

’k’入力後Enterキーを押すと、’Enter a character:’の表示が...続きを読む

Aベストアンサー

aaaa入力後→Enterキー
というのを実施すると、
下記のような実施結果になると思っていませんか?
-----------------------------
ASCII value of a is 97.

Enter a character:
Press any key to continue
-----------------------------

そんな風には思ってませんだったら、
スミマセン・・・なんですが、
もしそう思ってるのであれば、試しに実施してみて下さい。
(a→Enter を4回という意味では無いですよ。)
下記のように表示されるはずです。
キー入力後にどういう処理が実施されているのか、
実施結果を踏まえて考えてみてください。

-----------------------------
ASCII value of a is 97.
ASCII value of a is 97.
ASCII value of a is 97.
ASCII value of a is 97.

Enter a character:
Press any key to continue
-----------------------------

aaaa入力後→Enterキー
というのを実施すると、
下記のような実施結果になると思っていませんか?
-----------------------------
ASCII value of a is 97.

Enter a character:
Press any key to continue
-----------------------------

そんな風には思ってませんだったら、
スミマセン・・・なんですが、
もしそう思ってるのであれば、試しに実施してみて下さい。
(a→Enter を4回という意味では無いですよ。)
下記のように表示されるはずです。
キー入力後にどういう処理が実施されているのか、...続きを読む

QC言語 空白の行(改行のみ)が入力されたらプログラムを終了する処理

コンソールでうごくCUIプログラムを作っています。
そのとき文字列を入力してEnterキーを押すと、その文字列を格納したり何らかの処理をします。問題は何も入力せずにEnterキーを押された場合、プログラムを終了するという処理です。
どのようなソースになるのでしょうか?

Aベストアンサー

#include <stdio.h>

int main() {
 char buffer[256];
 char* result;
 do {
  result = gets(buffer);
  if ( result ) {
   printf("[%s]\n", result);
  }
 } while ( result && *result );
 return 0;
}

Q無限ループ内でのキー判別

DSPを用いたシステムを開発している途中なのですが。ループ内でのキー判別ができません。

whlie文で無限ループを行い,特定のキー(Enter等)が押されたらその動作を行うという判別ができません。
get関数等を無限ループの中で用いると,get文のところで止まってしまい,これでは私が求めている処理を行うことができません。

無限ループを行い,キー操作があった時だけその動作をする関数があれば教えてください。

PC:window7,visual stdio

Aベストアンサー

int c;

while( 1 ) {
if ( c = kbhit() ) {
switch( c ) {
case 0x0d:
         printf( "Enter Key\n" );
break;
    …
    …



の様に、kb_hit() が真の時に、getch() でキーコードを取得すればOKです。

キーコードを取得した後は、if 文か、switch文 (判別したいコードがたくさんある時は switch文がベター)で、それぞれのキーコードに従った処理を記述すれば良いです。

ご参考に。

Qfgetsなどのときのstdinのバッファを消すには?

こんにちは,今C(C++でない)を使用しています。
たとえば,
char str[20]
fgets(str,sizeof(str),stdin)
としたときに20字以上を打つと,stdinのバッファに20字以上の分が残ったままになります。

C++などでは
fflush(stdin)で,うまくいきますが,普通のCでは対応がされていないみたいでうまくいきません。

よろしくお願いします。

Aベストアンサー

あ,テキスト入力だからこんな大掛かりなことしなくてもいいんだ.
末尾に'\n'が出るまで掃出せばいいんですよね.

fgets(str, sizeof(str), stdin);
if ( str[strlen(str)-1] != '\n' ){
while( getchar() != '\n' );
}

でいいんだ.失礼しました.

Qfgetsで拾われる改行文字を削除したい

お世話になります

 C言語初心者のものです。今課題でC言語を用いたプログラミングを
Fedora上でやっています。問題は、fgetsでテキストファイルから、取得
した文字列の中から改行文字を削除できないことです。文字変数のアド
レスはわかっているのですが、終端文字に置換しようとすると、セグメ
ントエラーになってしまいます。これは如何にして解決すべきでしょう
か。よろしくお願いします。

Aベストアンサー

ポインタとかアドレスとか、C言語の用語としてあるものを別の意味に使うとまぎらわしいです。

「ポインタ」「アドレス」と言われたら、 この例なら str, str+i が思い浮びます。
「文字変数のアドレス」だと
char c ;
に対しての
&c
が思い浮びます。

配列なら「添字」、意味的には「x文字目」ですね。

> for(i=0;;i++){
> if(*(str+i)=='/n') {
> *(str+i)='\0';
> break;
> }
> }
/nが\nの間違いなら、この方法で半分正解です。もう少し広い範囲(可能なら全体)で見ないことにはなんとも言えません。
fgetsが最大文字数に達したり、ファイルの最後になったりで、strに改行文字が含まれない場合には、このループは止まりません(Segmentension Falutになって止まる)

・そのような状態になってないか、予めチェックする
・ループを終了させる仕組みを用意しておく
: forの終了条件を記述する、for中で if(*(str+i)=='\0') { break;} 等としておく、等
といった対策が必要です。


あと細かいところを言えば
・strを配列で用意したなら *(s+i)じゃなくてs[i]でいいんじゃないかな
・あるいは char *pみたいにしておいて、 iのループでなく pでループを組む( for(p=str;*p!='\0';p++) )とか。

ポインタとかアドレスとか、C言語の用語としてあるものを別の意味に使うとまぎらわしいです。

「ポインタ」「アドレス」と言われたら、 この例なら str, str+i が思い浮びます。
「文字変数のアドレス」だと
char c ;
に対しての
&c
が思い浮びます。

配列なら「添字」、意味的には「x文字目」ですね。

> for(i=0;;i++){
> if(*(str+i)=='/n') {
> *(str+i)='\0';
> break;
> }
> }
/nが\nの間違いなら、この方法で半分正解です。もう少し広い範囲(可能なら全体)で見ないことにはなんとも言えません。
fgetsが...続きを読む

Qscanf("%s", buf);でスペースを含んだ文字

コンソールプログラムで
scanf("%s", buf);
を使用してユーザに入力された文字によって処理を行いたいのですが、このままではスペースを含む文字列がスペースの手前で切られてしまいます。
C:\Program Filesなどを入力可能にさせたい場合にはどのようにするのがベターですか?

Aベストアンサー

お任せください!
そもそもscanfを使うというのはお勧めでは
ありません。scanfは文字+改行文字が入力
されないと完了しないためです。
が、それは良しとしましょう。
scanfの書式ですが、

int n = scanf("%[^\r\n]",buf);

という便利な書式があります。
perlでもおなじみの書式ですね。
上記の山文字"^"より前が読み込ませたい文字の集まりで、ハイフン指定が出来ます。
"^"より後ろが読込みを停止させたい文字の集まりです。上記の指定は復帰改行以外の文字が現れるまで読み込みます、という書式です。
下記のような指定も出来ます。

int n = scanf("%[a-zA-Z0-9\\: \t^\r\n]",buf);

なお、戻り値は読み込んだ項目数ですので、
if(n >= 1)
{
}
で判断できますね。

Q数字以外が入力されたらエラー文を出したい。

scanfで数字を取り込みたいのですが、ここでaなどのアルファベットや記号を入力すると、無限ループが発生してしまいます。
エラーが出ないように、数字以外が入力されたら、エラーメッセージを出すようなプログラムを作りたいのですが、どうすれば出来るでしょうか。

Aベストアンサー

★アドバイス
>scanfで数字を取り込みたいのですが、ここでaなどのアルファベットや記号を入力すると、
>無限ループが発生してしまいます。
 ↑
 ソースとかを見せて欲しいです。
 見ないとなぜ無限ループするのか判断できません。
>エラーが出ないように、数字以外が入力されたら、エラーメッセージを出すようなプログラムを
>作りたいのですが、どうすれば出来るでしょうか。
 ↑
 多分、scanf で整数の入力を行っていると思うので文字列で入力するようにします。
 そしてそのその文字列を strtod() 関数で整数に変換します。
・このときグローバル変数の errno を調べて ERANGE なら整数値のオーバーフローが起きたとか、
 第2引数で私のポインタに変換できなくなった位置をセットしますので、このポインタが \0 文字
 以外なら数字以外(アルファベットや記号)が混ざっていることになります。
・下にそのサンプルを載せます。

サンプル:
char buff[ 256 ];
char *argp;
int value;

// 文字列で入力
scanf( "%s", buff );
value = strtol( buff, &argp, 10 ); ←10進数で変換

// ここでチェック
if ( (errno != ERANGE) && (*argp != '\0') ){
 printf( "変換不可能な文字が入力されています。\n" );
 exit( 1 );
}

その他:
・上記のサンプルを使うには errno.h をインクルードして下さい。
 このヘッダに ERANGE 定数が定義されています。
 あと stdlib.h もインクルードしないと strtol() 関数が利用できません。
・以上。下の『参考URL』もどうぞ。

参考URL:http://www9.plala.or.jp/sgwr-t/lib/strtol.html

★アドバイス
>scanfで数字を取り込みたいのですが、ここでaなどのアルファベットや記号を入力すると、
>無限ループが発生してしまいます。
 ↑
 ソースとかを見せて欲しいです。
 見ないとなぜ無限ループするのか判断できません。
>エラーが出ないように、数字以外が入力されたら、エラーメッセージを出すようなプログラムを
>作りたいのですが、どうすれば出来るでしょうか。
 ↑
 多分、scanf で整数の入力を行っていると思うので文字列で入力するようにします。
 そしてそのその文字列を str...続きを読む


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

人気Q&Aランキング