質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

2回答

1031閲覧

C言語で テキストファイル読み込み

kokok

総合スコア145

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

1クリップ

投稿2019/07/28 05:29

編集2019/07/28 07:07

c

1#define WORLD_H 38 2#define WORLD_W 38 3 4void fileop(char temp[WORLD_H ][WORLD_W]){ 5 6 FILE* fp; 7 char txt; 8 char fname[] = "sample_data2.txt"; 9 10 fp = fopen(fname, "r"); 11 if (fp == NULL) { 12 printf("%s file not open!\n", fname); 13 14 return -1; 15 16 } 17 18 for (int rread = 0; rread < WORLD_H; rread++) { 19 20 for(int cread = 0; cread < WORLD_W; cread++){ 21 22 txt = fgetc(fp); 23 24 if (txt == '\n') { break; } 25 26 else if (txt == '1'){ 27 28 temp[rread][cread] = 1; 29 } 30 else if (txt == '.') { 31 32 temp[rread][cread] = 0; 33 34 } 35 36 37 } 38 39 } 40 fclose(fp); 41 42} 43

sample_data2.txt
......................................
.........................1............
.......................1.1............
.............11......11............11.
............1...1....11............11.
.11........1.....1...11...............
.11........1...1.11....1.1............
...........1.....1.......1............
............1...1.....................
.............11.......................
......................................
......................................
......................................

sample_data2.txt を読み込んで 配列に格納したいのですが、上手くいきません。
アドバイス頂けると幸いです。

------------------追記------------------------------
関数はmain関数から下記のように呼び出してます。
fileop(map);

.のところは. で 1のところは@ で 表示したいですが 

実行すると、 すべて. で表記されてしまっています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_waiwai

2019/07/28 05:36

うまく行かないとはどうなるんでしょうか。そこらへん説明しましょう
rubato6809

2019/07/28 06:55

テストデータ(sample_data2.txt)の内容が、上手くいく・いかないを判別しやすいデータだとは言えないですね。例えば、先頭の2~4行位を、先頭と最後が判別しやすいように、 1000...(途中省略)...0001 0111...(途中省略)...1110 とすれば、どう上手くいかないか、確認しやすいし説明もしやすいのではないでしょうか? もう一つ、そのためにも fileop() を呼び出す側の関数も一緒に提示したほうが良いと思う。質問者は具体的にどう確認してるのか、呼び出し方も関係無いとは言えないので。
rubato6809

2019/07/28 07:19

> .のところは. で 1のところは@ で 表示したい それを表示するのは、 fileop() ではなく、main() 関数なのだから、ますます main() がどうなってるかが肝心ではないか。
jimbe

2019/07/28 07:20

fgetc の直後に printf("%d,%d,'%c'¥n",rread,cread,txt); を入れて, 各変数の値がどう変化しているかの確認の結果をご提示願えますか.
kokok

2019/07/28 07:28

0,0. 世代97 ...................................... 0,3. ...................................... 0,5. ...................................... 0,7. ...................................... 0,9. ...................................... 0,11. ...................................... 0,13. ...................................... 0,15. ...................................... 0,17. ...................................... 0,19. ...................................... 0,21. ...................................... 0,23. ...................................... 0,25. ...................................... 0,27. 0,28. 0,29. 0,30. 0,31. 0,32. 0,33. 0,34. 0,35. 0,36. 0,37. 1,0 2,0. 2,1. 2,2. 2,3. こんな感じで表示されます。
rubato6809

2019/07/28 07:41

「世代97」って、いつ・どこで表示してるの? 何世代も動かして97世代になった? ファイルの読込みの問題なのか、ライフゲームの中の、どこか別の場所の不具合なのか、切り分けをしてほしい。 ファイルからの<読み込みだけ>をテストして、うまくいくかどうか、確かめたほうが良いと思う。そのためには、main() 関数をできるだけ簡単にすると良いです。
kokok

2019/07/28 07:45

世代97は ループして増えているだけです。 2,3. 以降もずっと表示されております。 参考にします!
guest

回答2

0

ベストアンサー

いくつかまずいところがあるので指摘しておきます
提示されてるまずいところがこれで治るかどうかはわかりませんが

  • txt = fgetc(fp);このtxtがcharなのはまずいです

fgetcの返り値はintです。これをintで受けないと、EOFの判定ができません。
ファイル終了のチェックしてないので、チェック入れておきましょう

  • txtが、\nでも1でも.でもないときには配列になにも入りません。

それはまずいでしょう

  • 1行づつ配列に入れるのであれば、
    for(int cread = 0; cread < WORLD_W; cread++){
    のループのあと、\nが出てくるまでfgetcして読み飛ばさないとダメです

そうじゃないと次の行の先頭に\nが出てくるなどして行がめちゃくちゃになります

で、おそらく結果のプリントアウトにも問題がありそうですが、そこんところのコードがないのでそこはパス

投稿2019/07/28 10:06

y_waiwai

総合スコア87719

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ああ、でも大体わかった感じがするのでツバつけておこう(笑)

内側の for ループが終了する条件が2つあって、ここに不具合の原因がありそうだ。

  • cread < WORLD_W という条件。即ち cread が 38 になれば終了する
  • txt == '\n' の時、break でループを強制終了する

P.S.1
fgets() で一行をまるごと読み込んでから、その一行を調べる、という手順も可能。

P.S.2
void fileop() 関数の中で、return -1; してるから、コンパイラは警告(warning)を出してるはず。警告の無い状態のコードを示していただきたいものだ。警告の対処法がわからなかったら、それも質問すればよいし。

投稿2019/07/28 07:10

編集2019/07/28 07:15
rubato6809

総合スコア1380

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kokok

2019/07/28 07:36

解答ありがとうござます。 void なのに return で-1 を返してるので警告を出しているのは分かりました。 しかし、return -1 を消してしまうと 警告 C6387 'fp' は '0' である可能性があります: この動作は、関数 'fclose' の指定に従っていません。これが行われる可能性のある以前の行 206 を参照してください 警告 C6387 'fp' は '0' である可能性があります: この動作は、関数 'fgetc' の指定に従っていません。 上記の警告が新しく出てしまいます。 void をint に変えるとエラーになります。 アドバイス頂けると助かります
rubato6809

2019/07/28 07:44

return -1; ではなく return; だけにすればよい。
kokok

2019/07/28 07:49

ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問