• ベストアンサー

無限ループに陥ります

プログラム中の以下の部分で無限ループに陥ってしまいます while(*a != EOF){ *a = fgetc(fi); if(*a == 32){ b++; } if(b == 3){ b = 0; t = *(a-1); if(t == '1'|| t == '3' ||t == '5' || t == '7'|| t == '9'){ c[n] = 1; } else{ c[n] = 2; } n++; } } fiに読み込んでいるファイルの末尾はこんな感じです。 50 49 0 34 34 34 34 34 34 34 34 34 34 34 34 50 49 0 68 68 68 51 51 50 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 [EOF] どなたか分かる方お願いします。

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

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.10

全然本題と関係ないんだけど, a は初期化しなくていいの? あと, EOF は「負の整数」としか定義されていないので, char では表せないかもしれませんね>#8.

その他の回答 (9)

  • yama5140
  • ベストアンサー率54% (136/250)
回答No.9

>無限ループに陥ってしまいます  《これだけ》を解決するには、 ☆ a の前の * を取る(なにか意図があって付けたハズ◆だが)。 ☆ fgetc の逆手をとる。  でいいのでは・・(動作確認済み)。  http://www.bohyoh.com/CandCPP/C/Library/fgetc.html    while( a != EOF ){     a = (unsigned char)fgetc( fi ); ---------------------------------- 《◆本題》 ・半角空白をデリミタにして、前に読み込んだものを、使いたいみたいだけど、それはムリなんでは・・。  *a = fgetc( fi ); 同じ場所に上書きされてんじゃないかな。  下のようにすると、空白に囲まれた数字の下1桁が、ファイルの終了まで得られるよ。   int iVal[ 1 ];   while( 1 == fscanf( fp, "%d", iVal ) ){     t = iVal[ 0 ] % 10; ---------------------------------- なお、上のようにしたら関係ないけど、  if( a == 32 ){ は、( a が char であることを明示するため)  if( ' ' == a ){ または、if( 0x20 == a ){  とコーディングした方が「後々」よろしいかと・・。

pwpr
質問者

補足

ポインタに代入するするたびに勝手に代入位置が一個進むもんだと勘違いしてました。。 他にもいろいろ理解があやふやな部分があるようです。 すこし勉強しなおしてきます。

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.8

★アドバイス >特にオプションなどがない限り、charの範囲は-128~127ですが。  ↑  処理系によってはcharをunsigned char型として扱う場合があるでしょう。  だからオプションを設定しなくてもcharが-128~+127かどうかは分かりません。  今回はchar型ですとなっています。  charの指定がsigned char型なら『while(*a != EOF){』の部分も抜けるはず。  無限ループするとなっているのできっとchar指定がunsigned char型となる  コンパイラかもしれない。と思ったのです。0x00~0xFF。 ・そもそもfgetc()関数の戻り値はint型なのでchar型(signed,unsignedも含む)の  変数に代入しているのが間違いですね。  あと良く考えたら変数aはchar型なのにポインタみたいに使っていますね。  本当に『char a;』なのでしょうか?  『char s[256], *a=s;』なのか?  どちらでしょうね。  『char a;』が正しいなら『t = *(a-1);』この指定はおかしいです。 ・質問者さんへ全ソースを貼り付けてみて下さい。

pwpr
質問者

補足

以下が全ソースです。 ちょこちょこいじってますが問題は解決していません。 #include<stdio.h> int main(void) { FILE *fi; char fname[100], ss[255], t, ch; int count, b, n, *a, err, c[1000]; printf("file name?\n"); gets(fname); fi = fopen(fname,"r"); fgets(ss,255,fi); puts(ss); printf("are"); if(ss[0]!='P') err = 1; if(ss[1]!='3') err = 1; if(err ==1){ printf("file type is wrong\n"); exit(1); } while(count < 3){ *a = fgetc(fi); printf("%d",*a); if(*a =='\n' ){ count++; } if(*a == '#'){ count--; } } b = 0; while(1){ *a = fgetc(fi); if(*a == EOF){ break; } if(*a == '\x20'){ b++; } if(b == 3){ b = 0; t = *(a-1); if(t == '1'|| t == '3' ||t == '5' || t == '7'|| t == '9'){ c[n] = 1; } else{ c[n] = 2; } n++; } } n = 0; while(c[n] !=0){ count = 0; while(count < 8){ if(c[n] == 1){ ch++; } ch = ch + ch; count++; n++; } printf("%c",ch); } fclose(fi); }

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.7

> char型は0x00~0xFFまでを扱います。 特にオプションなどがない限り、charの範囲は-128~127ですが。 でも、だとすると動くはずだよな。 本当にcharですか?unsigned charではなくて。

  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.6

#5です。 前回のは取り消します。 終了条件の判定は、int型のデータで処理する必要があるが、 1文字の処理で、t = *(a-1); を行っているとことは、 int型にすると、おかしくなるので、だめですね。 最初のところを、以下のようにして下さい。 ---------------------------------- int data; while(1){ data = fgetc(fi); if (data == EOF) break; *a = data; /* *a = fgetc(fi); のところです。*/ -------------------------- 以下同様 }

pwpr
質問者

補足

ありがとうございます。 試してみます。

  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.5

char *a を int *a にして下さい。それで解決します。原因は、#4の方が述べたとおりです。

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.4

★アドバイス ・記号定数EOFの値は何?  char型は0x00~0xFFまでを扱います。  char型ではファイルの最後のEOFを表せません。  int型ならEOF、1バイトの0x00~0xFFを表せます。 ・さて気づきましたか?

  • koko_u_
  • ベストアンサー率18% (459/2509)
回答No.3

>char型です それもおかしな話だな。 fgetc() のプロトタイプ宣言を見よ。

pwpr
質問者

補足

すみません、色々調べましたがよくわかりませんでした。。

  • SAYKA
  • ベストアンサー率34% (944/2776)
回答No.2

ループ中 どこか何か表示するようにして 何が起きてるか把握するところから始めるのが良いんじゃない?

pwpr
質問者

補足

読み込んだ後すぐに*aを出力してみたところ、ファイルの内容は正しく表示されましたが、ファイルの終わりを認識せずに処理を続けているようでした。 *a!=EOF の部分が問題なのでしょうか

  • koko_u_
  • ベストアンサー率18% (459/2509)
回答No.1

a の型は?

pwpr
質問者

補足

char型です

関連するQ&A