printf()で出力できない理由と修正方法

このQ&Aのポイント
  • このプログラムはコンパイルはできますが、printf関数での出力ができません。
  • 可能な理由としては、関数の使い方が間違っている可能性や、DO~WHILE文が使えない場所に書かれている可能性が考えられます。
  • 修正する場合は、まず関数の使い方を確認し、正しい引数を渡しているか確認してください。また、DO~WHILE文が使えない場所に書かれている場合は、別のループ構造に置き換えてください。
回答を見る
  • ベストアンサー

printf()で出力したいんですが?

#include <stdio.h> int main( void ) { int air[4]; int i; i = 0; printf( "データ入力\n" ); do{ scanf( "%d\t", &air[ i++ ]); } while(air[ i - 1 ] > 0 ); printf( "%d\n", i ); return 0; } このプログラムはコンパイル出来ますが、期待していたprintf関数での出力ができません。 その理由として何がありますか?関数の使い方が間違っているのか、DO~WHILE文が使えない場所 なのか、もし直すとすればどう直せばいいのですか。

質問者が選んだベストアンサー

  • ベストアンサー
  • Glory_777
  • ベストアンサー率50% (105/208)
回答No.4

こんにちは。 整数以外か、0以下の整数が入力されると脱出する仕様で良いのかな? 配列が4つまでしか用意されていないので、値を入れ続けると、飛びますが・・・。 まずは練習と言うことでしょうね。 脱出した時、入力した数が表示される意図のようですね。 一見して問題無さそうに見えますが・・・嫌な予感がしますね。 コンパイラを立ち上げて確認しました。 嫌な予感はしましたが、やはりscanfです。 scanf("%d\t",&air[i++]); ===> scanf("%d",&air[i++]); 私も相当昔にはまったのがscanfです。 今回の例は、入力フォーマットにタブ文字が入ってたからのようです。 改行コードに変えてやってみましたが、やはり不可思議な動作をします。 画面では入力が終わったように見えて、scanfが入力待ちになっています。 入力終了を意味するリターン押下が一回分消えてしまい、 本人(私)は2個目のデータを入力しているつもりが、 最初のscanfを脱出していないようです。 これで一つ入力がズレてしまいます。 脱出条件である、0以外、0以下の整数を入力しても、 入力した気になって、リターン押下は無視されてしまい、実際はまだ入力中と言う事です。 確か、scanfを使ったサンプルは初心者殺しで有名だったと思います。 前述のとおり、タブ文字列を抜いて試してみてください。 以下は蛇足ですが、助言です。 初心者向けの本にはstdioを使ったサンプルが多いのですが、 do,While文もお勧めしませんし、scanf関数もお勧めしません。 いずれは、標準入力に変わる何らかの入力関数を使うようにステップアップすると思いますから、 最初は仕方ないとします。 しかし、 基本的なループ文については、以下の定型で覚えると良いです。 「for if break」 と唱えて覚えましょう。 25年くらいC言語を書いています。 その間に指導もしましたが、初心者を半年でベテラン並みに鍛えるポイントがあります。 「仕組みを教えよう」とか、「スタイルを教えよう」とか誘惑に駆られるものですが、 これはあくまでも知識であって実利に乏しいです。 大事なのは、徹夜でフラフラの状態でも楽にコードが組めるかどうかです。 自己流ですと色々と迷い、どうつくっても大丈夫と思えるものです。 しかし、睡眠不足のときに自分を助けてくれる、疲れない考え方と言うのは存在します。 今回の場合は、 --------------------------------------------------- int air[4]; int i; for( i=0; i<4; i++ ) { scnaf( "%d" , &air[i] ); printf( "--->%d\n" , air[i] ); if( air[i] <= 0 ) break; } printf( "===>%d\n",i ); --------------------------------------------------- と、for文の役割と脱出条件をわけて書くのがバグを作らないコツです。 for文は、配列等のリソース数をオーバーラン(超えてループする)しない ための条件だけをシンプルに書きます。 このとき、ループのはじめが0からなのか1からなのか、 大きさで比較するのかイコールを含むのかで、悩みます。 ですのでこう覚えます。 「ループ数は、0からはじまり<で条件を作ると間違いなくその回数ループする」 for( i=0 ; i<回数 ; i++ ) として覚えてしまえば楽です。 演算結果や処理の途中でのイレギュラーにより脱出する場合にifを使います。 if( xxx ) break; です。こうしておけば、ループが終わる条件を分けて考えることが出来、 後で仕様が変わったときにも直しやすいのです。 例えば、配列の中にあるデータを検索して返却する処理にも応用できます。 --------------------------------------- #define MAXINDEX 20 static int data[MAXINDEX] = { 0, 1, 2 ,3 , 4, 5 }; int sample( int val ) { int i; int ret = -1; for( i=0;i<MAXINDEX; i++) { if( data[i] == val ) { ret = i; break; } } return( ret ); } --------------------------------------- 何よりも、自分でコードを書くときに、こうやって統一しておくことが大事です。 一つ一つのコードが、自分のルールと反しているところに目が行くようになります。 これでミスが分かる。 長いプログラムを作っても疲れなくなります。 C言語はシンプルすぎて、本を読んで理解する部分が少ないです。 物足りたいと感じて不安になる人が、どうでも良い細かい部分を勉強しがちです。 実際は、一日で1Kラインのプログラムを書く人同士が、寝ないでコードを書き続け、 先に能力が落ちたほうが負けると言う世界です。 疲れないに越したことは無いですよ。 このレベルに達すると、便利な関数を探して使い方を覚えるより早く、自分で作れます。 また、製品として人に売れるもの作るには、プログラミング能力よりもデバッグ能力 が高い人のほうが上にいきます。 ある程度慣れたら。 しっかりとした設計法と試験項目の抽出方法を学ぶと良いと思いますよ。 以上ご参考になれば。

okikayo
質問者

お礼

有難うございます。解りやすかったです。

その他の回答 (4)

回答No.5

あなたの期待する入力、期待する出力をもっと具体的に説明してはいかがでしょうか。 あなたが何を期待しているのか誰にもわからないので、このままではまず的を射た回答は得られないと思います。 一応これまでの質問を読ませてもらいました。 http://okwave.jp/qa/q8503397.html http://okwave.jp/qa/q8503486.html これらから予想すると、いくつかの数字を入力させて、それを表示させたいのではないかと思ったのですがどうでしょうか。 まあ、人が書いたプログラムというのも何かの勉強の足しになると思うので一応書いてみます。 プログラムの説明) ユーザーからn (n <= 4) 個の自然数を受け取り、それをスペースで区切って表示する。 ユーザーが0以下の値を入力すると受け取りが終了する。なお、表示にその0以下の数値は含まれない。 また、数値が4つ入力されると自動的に受け取りを終了し、表示を行う。 動作例) input? (ユーザーからの入力)10(改行) (ユーザーからの入力)25(改行) (ユーザーからの入力)-1(改行) 10 25 コード) #include <stdio.h> #define INPUT_SIZE 4 int main(void) { int input[INPUT_SIZE]; int input_size; printf("input?\n"); for (input_size = 0; input_size < INPUT_SIZE; input_size++) { scanf("%d", &input[input_size]); if (input[input_size] <= 0) break; } for (int i = 0; i < input_size; i++) { printf("%d ", input[i]); } printf("\n"); return 0; } あと、http://okwave.jp/qa/q8503486.htmlを見ていて、数値をシャッフルして出力するということもやりたいのかと思ったので、0から9までの数値をシャッフルして表示するプログラムも参考までに乗せておきます。 #include <time.h> #include <stdio.h> #include <stdlib.h> #define NUMELMS(X) (sizeof(X) / sizeof(X[0])) int random_int(int upper_bound) { if (upper_bound < 2) return 0; int min = ((RAND_MAX % upper_bound) + 1) % upper_bound; for (;;) { int r = rand(); if (r >= min) return r % upper_bound; } } void shuffle(int x[], size_t s) { for (size_t i = 0; i < s; i++) { int r = random_int(i + 1); int t = x[i]; x[i] = x[r]; x[r] = t; } } void print_all(int x[], size_t s) { for (size_t i = 0; i < s; i++) { printf("%d ", x[i]); } printf("\n"); } int main(void) { srand(time(NULL)); int x[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; shuffle(x, NUMELMS(x)); print_all(x, NUMELMS(x)); return 0; } 一応、すべてFreeBSD 10.0Rのclangでコンパイルして、動作確認はしていますが、C99を理解しないコンパイラーを使っているとコンパイルが出来ないかもしれません。 余談ですが、 okikayo さんのコードでいつも気になるのは配列のサイズ以上に値が入力される可能性を考慮していないことです。これはセキュリティー上の欠陥やプログラムのクラッシュを引き起こす欠陥になりえるので注意したほうがよいです。 あと、好みの問題も多々あると思いますが、関数を使うことや制御構造を変えることを考慮して、それでもどうしてもこの構造がよい時にのみdo-while文を使ったほうがよいと思います。条件の確認があとに来るという構造上、本来実行すべきでないコードを実行してしまったり、配列の添字の取り扱いを間違ったりとミスを起こしやすいですので。

okikayo
質問者

お礼

ありがとうございます。まだ始めて一月なもんでわからない事だらけ

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.3

しつこいようですけど 何を「期待」していて、それがどうなっているのですか? それがはっきりしないことには、直すことなどできません。 「コンパイルできる」というのは。文法的に間違っていない、というだけです。 プログラムが期待通りになっているかどうかは、まったく関知していません。 「配列airに値を読み込んだ数」なら、現在の記述の通りです。 「配列airに値を読み込んだ**正の値の数**」なら、最後に読んだ「0以下の数」の分を除く必要があります。 あるいは、最初から「正の値の数」だけを数えるようにします。 初級者なら、まずは「日本語」で「手順書」を書きましょう。 そして、その指示通りに自分で「実行」してみましょう。 その時、「書いてある通りにやる」こと。曖昧な言葉とかがあっても勝手に都合のいい解釈はしないことです。 C言語に直すのは、その後です。

okikayo
質問者

お礼

ありがとうございました。解りやすかったです。

  • ninoue
  • ベストアンサー率52% (1288/2437)
回答No.2

何を期待していて何が出力されたのですか? それから 90,91,92,93,94,95 等と次々に正の数を入力し続けた時にどうなりますか? 入力が正しくair[]の配列に入ったかどうかを確認しなくてよいのですか? この程度の簡単なプログラムは自分で1ステップずつ机上デバッグで直ぐに見つけるようにして下さい。

  • wormhole
  • ベストアンサー率28% (1619/5654)
回答No.1

>このプログラムはコンパイル出来ますが、期待していたprintf関数での出力ができません。 以前の質問もそうなのですが、「期待していたprintf関数での出力」と書かれても他者には、それがどのような期待なのかわかりません。 例えば、 #include <stdio.h> int main(int argc, char **argv) { printf("%d\n", argc); return 0; } 上記プログラムで私が「期待する動きをしません。どこを直せばよいでしょうか」といった質問を場合、あなたには上記プログラムに私が期待する動作わかりますか?

関連するQ&A

  • printf scanf が、反応しません。

    printf scanf が、反応しません。 #include <stdio.h> int main(void) { int num = 0; int sum = 0; printf("テストの点数を入力してください。(0で終了)\n"); do{ scanf("%d", &num); sum += num; }while(num); printf("テストの合計点は%d点です。\n", sum); return 0; } C:\WORK>gcc test1.c C:\WORK>gcc -o test1 test1.c おかしいです。 打開策を教えてください。 ご多忙中恐れ入ります。 ご回答のほど、宜しくお願い申し上げます。

  • printfが後で実行されます。

    最近、プログラミングを始めた初心者です。 エクリプスを使い、次のようなプログラムを作ったのですが、 実行結果が思いと違うのです。 #include<stdio.h> int main(void) { int i, dt; printf("数値を入力:"); scanf("%d", &dt); i = 2; while(dt != 1) { while(dt % i == 0) { dt = dt / i; printf("%d\n", i); } i ++; } return 0; } 実行結果 60 数値を入力:2 2 3 5 数値を入力:の後に、scanfで入力したいのですが、 入力したあとでないと、printfの内容が表示されないのです。 コードは大丈夫だと思うのですが、、、 初心者なので、何をどうすれば解決するのか検討もつきません。 どなたかお分かりになる方、よろしくお願いいたします。

  • コンパイルエラー

    コンパイルしても、12行目(printf("%d番目の整数を入力してください。"i+1);が、関数呼び出しに)がないとでます。でもどこが間違っているか分かりません。 教えてください。お願いします。 #include <stdio.h> int main(void) { int num; int sum=0; int i; for(i=0; i<10; i++){ printf("%d番目の整数を入力してください。"i+1); scanf("%d", &num); sum+=num; } printf("合計は、%dです。\n", sum); return(0); }

  • printfを代入する?

    #include <stdio.h> int main(void) { int kaerichi,nyuuryokumoji; char moji[40]; printf("\n数字を入力してください:"); scanf("%d",&nyuuryokumoji); kaerichi=printf("%d",nyuuryokumoji); printf("\n入力数字の桁数は%dです\n",kaerichi); printf("\n文字を入力してください:"); scanf("%s",&moji); kaerichi=printf("%s",moji); printf("\n入力された文字は%dです\n",kaerichi); return(0); } このプログラムでkaerichi=print("d",nyuuryokumoji); とありますがどういう意味でしょうか? 変数に数字などを入れるのはわかるのですが printfをいれるというのがあまりよくわかりません あとどうして桁数がでるのでしょうか?

  • getchar()について 教えてください。

    visual studio 2010 professinalで以下のソースをデバッグして ”続行するには何かキーを押してください!”  で待機させたいのですが getchar()一個だけでは実現しません。   2個重ねるとOKです。どうしてでしょうか。  -------------- 以下のようにscanf関数がなければokということは突き止めたのですが、、、。  ご教授ください。 #include <stdio.h> int main(void) { int i; printf("なにか数字を入力してください。\n"); scanf("%d",&i); printf("今あなたが入力した数字は%dです。\n",i); printf("続行するには何かキーを押してください!"); getchar(); //getchar(); return 0; } ---------------------------------------------------------------- int main(void) { printf("続行するには何かキーを押してください!"); getchar();   return 0; }

  • c言語で平均をだす

    #include<stdio.h> int main(void) { int num; int sum; printf("テストの点数を入力してください。\n"); do{ scanf("%d",&num); sum+=num; }while(num); printf("テストの合計点は%dです\n",sum); return 0; } テストの平均点をだすプログラムを作りたいのですが、合計を出すまではわかったのですが、ここから、平均を出すようにするにはどうすればよいですか。

  • おみくじプログラムですがじっこうできません。

    #include<stdio.h> int main() { int i; char data[5][10]={"大吉","小吉","吉","凶","大凶"}; printf("1~5の間の整数を入力:"); scanf("%d",&i); while(i<1&&i>5){ printf("入力値が不適切です。\n"); printf("1~5でお願いします。\n"); scanf("%d",&i); } printf("%s\n",data[5][i-1]); return 0; } 自分で考えてみたのですが、どうしたらいいかわかりません。

  • ループ

    #include<stdio.h> int main(void) { int i=1,sum=0; int num=1; while(num>0) { printf("整数を入力してください。(マイナスの値で終了)\n"); scanf("%d",&num); printf("%dが入力されました。(%d番目の繰り返しです)\n",num,i); sum+=i; printf("1から%dまでをたすと%dです。\n",i,sum); i++; } printf("繰り返しが終わりました。\n"); printf("加算値は%dです。\n",sum); printf("%d回繰り返しました。\n",i); return 0; } このプログラムで101以上の数値は加算しないようにするにはどうすればいいですか。

  • インクリメント演算子をprintf文で使うことについて

    ◎1-------------------------------------- #include<stdio.h> int main(void) { int i=0; while(i<=20){ printf("%d\t%d\t%d\t%d\t%d\n",++i,++i,++i,++i,++i); } return 0; } ------------------------------------------ ◎2-------------------------------------- #include<stdio.h> int main(void) { int i=0; while(i<=20){ printf("%d\t%d\t%d\t%d\t%d\n",i++,i++,i++,i++,i++); } return 0; } ------------------------------------------ 以上2つのプログラムについて疑問があるのですが、まず◎1についてですが、実行結果は、 5    4   3   2   1 10   9   8   7   6 15   14   13   12   11 20   19   18   17   16 25   24   23   22   21 以上のようになるのですが、自分の考えでは、「printf("%d\t%d\t%d\t%d\t%d\n",i++,i++,i++,i++,i++);」部分の、一番最初の「++i」から処理が始まり、 1  2  3  4  5      ・      ・      ・ のようになる事を期待したのですが、一番最後の「++i」から処理が始まってしまいました。 次に、◎2についてですが実行結果は、 0   0   0   0   0 5   5   5   5   5 10  10  10  10  10 15  15  15  15  15 20  20  20  20  20 以上のようになりました。「printf("%d\t%d\t%d\t%d\t%d\n",i++,i++,i++,i++,i++);」部分で、iをいったん表示してから、iに1を加算するということで、次のiは1になっており、 4  3  2  1  0      ・      ・      ・ のようにまた一番最後の「i++」から処理され以上のようになると思ったのですが、そうはなりませんでした。 以上、◎1と◎2について何故こうなるのかご回答いただければ嬉しいです。

  • C言語でmからnまでの合計を求めるプログラム

    これで動かないのですが、何が違っているのか、教えていただけますか。 #include <stdio.h> int main(void) { int m, n, sum, i, w ; printf("mからnまでの合計を求めます\n\n"); printf("m >> "); scanf(" %d", &m); printf("n >> "); scanf(" %d", &n); sum=0; if(m>n){ w=m; m=n; n=w; } sum=0; i=m; while(i<=n){ sum=sum+i; i=i+1; } printf("%d から %d の合計 = %d\n",m,n,sum); return 0; }

専門家に質問してみよう