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

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

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

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

ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

Q&A

解決済

1回答

872閲覧

C言語のファイル操作がよくわからないです

nachu_

総合スコア3

C

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

ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

0グッド

0クリップ

投稿2021/10/28 17:17

前提・実現したいこと

授業のプログラミングの課題でファイル操作をするところがあるのですが、なぜ正常に動かないのかがよくわかりません。
課題の内容は、バブルソートを用いて成績管理システムを作るといったものです。バブルソートに関してはある程度理解できたかと思うのですが、ファイル操作に関しては授業のメインでないこともありあまり説明がなく、調べてみてもよくわからなかったので、どう使えばいいのか十分に理解できていない現状です。
ファイルを読み込んで、その内容を構造体に格納したいのですが、実行すると名前がNULLで、それぞれの点数も0点と表示されてしまっているのですが、原因がわからず困っています。ご教授頂けますと幸いです。

該当のソースコード

C言語

1#include <stdio.h> 2#include <stdlib.h> 3 4#define seisekiMAX 256 5 6typedef struct{ 7 char name[seisekiMAX]; // 氏名 8 int kokugo; // 国語の評点 9 int sansu; // 算数の評点 10 int rika; // 理科の評点 11}Seiseki; 12 13 14int seisekiCount = 0; // ファイルの行数(=データの数) 15 16 17void putSeisekiArray(Seiseki*); // ファイルからデータを読み込み配列へ格納する 18void view(Seiseki*); // 構造体配列に格納されている各データを表示する 19void sort(Seiseki*); // 国語を基準に降順でバブルソート 20 21 22int main(){ 23 24 // 構造体配列の宣言 25 // seisekiMAXはメイン関数の外で#define で256に設定 26 // Seiseki 型もメイン関数の外で定義しているものとする 27 Seiseki seiseki[seisekiMAX]; 28 29 // putSeisekiArray の中でファイルからデータを読み込む 30 putSeisekiArray(seiseki); 31 32 // ソート前のデータを表示 33 printf("**** origin ****\n"); 34 view(seiseki); 35 36 printf("\n"); 37 38 // バブルソートを行う 39 sort(seiseki); 40 41 // ソート後のデータを表示 42 printf("**** sorted ****\n"); 43 view(seiseki); 44 45 return 0; 46} 47 48// ファイルからデータを読み込み配列へ格納する 49void putSeisekiArray(Seiseki* seiseki){ 50 FILE *fp; // FILE型構造体 51 char buf[256]; // ファイルの一行分を格納 52 53 54 // ファイルを開く。失敗するとNULLを返す 55 fp = fopen("data.txt", "r"); 56 if(fp == NULL){ 57 // ファイルオープンに失敗した場合の処理(異常終了) 58 printf("ファイルのオープンに失敗しました\n"); 59 exit(1); 60 } 61 62 // ファイルの内容を全行読み込む 63 while (fgets(buf, sizeof(buf), fp) != NULL){ 64 // 読み込んだデータを格納 65 sscanf( buf, "%s %d %d %d", (seiseki+seisekiCount)->name, &(seiseki+seisekiCount)->kokugo, &(seiseki+seisekiCount)->sansu, &(seiseki+seisekiCount)->rika ); 66 seisekiCount++; 67 } 68 69 // ファイルをクローズする 70 fclose(fp); 71} 72 73// 構造体配列に格納されている各データを表示する 74void view(Seiseki *seiseki){ 75 for(int i = 0; i < seisekiCount; i++){ 76 printf( "%s\n 国語:%d点 算数:%d点 理科:%d点\n", (seiseki+seisekiCount)->name,(seiseki+seisekiCount)->kokugo, (seiseki+seisekiCount)->sansu, (seiseki+seisekiCount)->rika ); 77 } 78} 79 80// 国語を基準に降順でバブルソート 81void sort(Seiseki *seiseki){ 82 Seiseki tmp; 83 84 for(int i = 0; i < seisekiCount-2; i++){ 85 for(int j = 0; j < seisekiCount-2-i; j++){ 86 if((seiseki+j)->kokugo > (seiseki+j+1)->kokugo){ 87 tmp = *(seiseki + j); 88 *(seiseki + j) = *(seiseki + j + 1); 89 *(seiseki + j + 1) = tmp; 90 } 91 } 92 } 93}

data.txt(読み込みたいファイル)

Ichiro 92 95 98 Jiro 70 75 80 Saburo 75 75 75 Shiro 95 90 85 Goro 83 80 77 Rokuro 85 75 65 Shichiro 50 70 90 Hachiro 60 40 20

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

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

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

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

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

jimbe

2021/10/28 17:24

※ご質問本題とは関係ありません > (seiseki+seisekiCount)->name, ~ ポインタは配列として使えますので seiseki[seisekiCount].name と書いたほうが分かり易いように思います。(人それぞれでしょうけれど。)
guest

回答1

0

ベストアンサー

ファイルの読み込みでは無く、表示のほうが間違っています。
表示のループの変数は i です。

「原因がわからず困って」いるだけでは何も変わりません。
誰かに聞くより先にまず何とか原因を探らなくてはなりません。この作業もプログラミングの一部なのですから。
簡単な所では、あちこちに printf を入れて変数の値を確認することです。
そもそもその表示がされなければそこを実行していないことになりますし、変数の値が想像と違っていれば、そこまでの間の何かで想像通りの動作をしていないことになります。
そのように情報を集めていって原因となる個所を見つけ、修正する・・・これを繰り返すことでプログラムが思ったように動作するようになります。
それでもいよいよ原因が絞れないとなったら個人の限界かもしれませんので、** コードに、それまで試したことを添えて** どこかにご質問されると良いでしょう。そこまでの調査で自身のプログラムがどこまでどう動いているかははっきり理解しているはずですので、提供する情報は具体的となり回答も付き易く、回答が付けばその理解も早くなると思います。

投稿2021/10/28 17:46

編集2021/10/29 02:38
jimbe

総合スコア12756

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

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

dodox86

2021/10/28 23:02

> println を入れて printfの誤記ではないでしょうか。(Javaとの混同かと思われますが、初心の方だと悩んでしまうかもしれませんので、小さいことながら指摘させていただきました)
nachu_

2021/10/28 23:36

ファイル操作に自信がなかったので、そこが問題だと思い込んでいました。どこが間違っているのか見当もつかなかったため質問しましたが、不足があったようで申し訳ないです。アドバイスありがとうございます。
jimbe

2021/10/29 03:04

>printfの誤記 あわわ、やってしまいました。ありがとうございます。 小さいことどころか一番大切な箇所でしたのに間違えるとは…。 >どこが間違っているのか見当もつかなかった 作り方を教えるところは多数あっても、動作がおかしい時の調べ方・直し方はなかなかきっちりはやらないでしょうね。組み合わせが無数になりますから。 その為動作すれば先に進めますが、動かなければ止まってしまうのは理解できます。 ただ、逆に考えれば、ここでこのようなバグを経験したことで、今後作られるであろうプログラムがおかしな動作が見られた時に、ファイルの読み込み(等の処理部分)だけで無く表示のほうも疑わなければならないことを知ったのは収穫ではないでしょうか。 自信がないと言われるファイル操作は問題ありませんでしたから、自信の"足し"にしてもよいでしょうし。(問題が無かったので余計に見当がつかなくなったとも言えますが(^_^;))
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問