現在、課題でsample.txtを構造体に入れたのちに新規でデータを入れることを実現したいとしているのですがうまく行きません。
今試している方法としては
0. define MAXCNT 100で配列の最大数を100に指定します。
0. そして、既存のデータ55件(sample.txt)をまずは構造体に読み込みます。
0. さらに、追加で既存の配列+1(ここでは56番目などに)新規にデータを入れ込む方法です。
これがうまくいかないのでうまくいく方法があれば教えてほしいです。
また、他に
- 読み込んだ名前データの表示が文字化けする(深�)みたいなバグもありますのでよければこちらもついでに教えてほしいです。
C言語できる方どなたかご教授いただきたいです。
よろしくお願いします。
sample.txt
1深津 旭弘 29 183 78 2深津 英臣 27 180 70 3藤井 直伸 25 183 78 4関田 誠大 23 177 70 5米山 裕太 32 185 85 6鈴木 悠二 35 190 80 7清水 邦広 30 193 94 8高松 卓矢 29 186 82 9栗山 雅史 28 190 85 10柳田 将洋 24 186 79 11山田 脩造 24 193 78 12高野 直哉 24 190 77 13小川 猛 22 193 90 14久原 翼 22 189 79 15石川 祐希 21 192 84 16鈴木 祐貴 20 201 85 17新井 雄大 19 188 86 18富松 崇彰 32 192 85 19李 博 26 194 83 20傳田 亮太 25 191 84 21出耒田 敬 25 200 92 22山内 晶大 23 204 72 23高橋健太郎 22 202 100 24大竹 壱青 21 201 100 25小野寺太志 21 201 98 26古賀太一郎 27 170 70 27浅野 博亮 26 178 69 28鶴田 大樹 25 177 76 29井手 智 25 174 74 30冨永こよみ 28 176 67 31佐藤 美弥 27 174 61 32田中 美咲 25 173 61 33宮下 遥 22 177 61 34石井 里沙 27 179 65 35新鍋 理沙 26 173 64 36長岡 望悠 25 179 64 37石井 優希 26 180 68 38野本 梨佳 25 180 73 39内瀬戸真実 25 171 70 40堀川 真理 25 183 70 41高橋 沙織 24 177 67 42鍋谷友理枝 23 176 57 43井上愛里沙 22 178 66 44田中 瑞稀 21 170 73 45古賀紗理那 21 180 66 46黒後 愛 19 180 69 47荒木絵里香 32 186 78 48松本亜弥華 28 188 71 49岩坂 名奈 26 187 76 50奥村 麻依 26 177 66 51島村 春世 25 182 77 52大野 果奈 25 180 70 53井上 琴絵 27 162 53 54佐藤あり紗 27 166 53 55小幡 真子 24 164 55
main.c
1/* 2- case2で年齢(age)27を表示するときだけ7になってしまうバグがあります。 3- 日本語を読み込んだ際に文字化けするバグがあります。 4char型-string型によるバグだと思う 5*/ 6 7#include <stdio.h> 8#define MAXCNT 100// sample.txtの行の最大許容数 9// 構造体定義の宣言 10// 参考:【B4】おまけ課題 4~10行目 11// 関数のプロトタイプ宣言 12int is_loaded(); 13// 参考:【B4】おまけ課題 12~14行目 14typedef struct Body 15{ char name; 16 // char name[10]; もしかしたらこっちの方がいいかも 17 int age; 18 int height; 19 int weight; 20}Body; 21 22int main(void) 23{ 24// 変数の宣言 25// 参考:【B4】おまけ課題 18~20行目 26 int i,j=0,max_num,flag=0;//初期値など 27 int tmp_age=0,tmp_height=0,tmp_weight=0;//平均の準備用 28 float avg_age,avg_height,avg_weight;//平均 29 char new_name; 30 int new_age,new_height,new_weight; 31 char fname[] = "sample.txt";//読み込むためのファイル名 32 Body Data[MAXCNT]; 33 FILE* fp; 34 35int menu; 36while(1){ 37printf("\n=== 操作メニュー ===\n"); 38printf("1:ファイル読み込み\n"); 39printf("2:全データ表示\n"); 40printf("3:新データ入力\n"); 41printf("4:ファイル書き出し\n"); 42printf("1~4以外:終了\n\n"); 43printf("操作No の入力:"); 44scanf("%d",&menu); printf("\n"); 45switch(menu){ 46case 1: 47// ファイルを開き 構造体配列に読み込む 48// 参考:【B4】おまけ課題 22~33行目 49fp=fopen(fname,"r"); 50if(fp == NULL){ 51 printf("ファイルを開けませんでした\n"); 52 return -1;//異常終了 53} else 54{ 55 printf("%s ファイルを開きました\n",fname); 56 // fread(fname,sizeof(char),10,fp); 57 printf("%s ファイルを読み込みました\n",fname); 58 for(i=0;i<MAXCNT;i++) { 59 if(fscanf(fp,"%s%d%d%d\n", 60 &Data[i].name, 61 &Data[i].age, 62 &Data[i].height, 63 &Data[i].weight) == EOF) break; 64 } 65 66 Data[56].name = '*'; 67 Data[56].age = 27; 68 Data[56].height = 130; 69 Data[56].weight = 61; 70 // Data[57].name = '*'; 71 // Data[57].age = 23; 72 // Data[57].height = 170; 73 // Data[57].weight = 40; 74 // printf("%d",Data[56].age); 75 76 77 fclose(fp); 78 printf("ファイルポインタを閉じました\n"); 79 flag=1;//case 2に映るためのフラグを持たせる 80 printf("サイズの確認:%d",i); 81} 82break;// case1 終了 83 84case 2: 85// 構造体配列の内容を1件1行として画面に表示 86// データ件数と、それぞれの項目についての全件の平均値を表示 87// 参考:【B4】おまけ課題 35~37行目 88// if(!is_loaded(flag))//テキスト読み込まれてるか 89// {break;} 90if (flag!=1){ 91 printf("\nファイル読み込みを先に実行してください\n"); 92 break; 93} 94else 95 { 96printf("データを表示する\n行数\t名前\t年齢\t身長\t体重\n"); 97while(1) { 98 printf("%d:\t%s\t%d\t%d\t%d\n", 99 j+1, 100 &Data[j].name, 101 Data[j].age, 102 Data[j].height, 103 Data[j].weight); 104 // 年齢、身長、体重の合計 105 tmp_age += Data[j].age; 106 tmp_height += Data[j].height; 107 tmp_weight += Data[j].weight; 108 if(j==i) break;//iはデータの読み込み件数(デフォルト55件) 109 j++; 110} 111printf("\n全データを出力しました\n"); 112// 年齢、体重、身長の平均 113avg_age = tmp_age/MAXCNT; 114avg_height = tmp_height/MAXCNT; 115avg_weight = tmp_weight/MAXCNT; 116printf("\n合計件数:%d\n",MAXCNT); 117printf("平均を表示\n"); 118printf("平均年齢:%f\t平均身長:%f\t平均体重:%f\n",avg_age,avg_height,avg_weight); 119break; 120} 121case 3: 122// 構造体配列に新データを追加する 123// 参考:【B4】おまけ課題 39~48行目 124if (flag!=1){ 125 printf("\nファイル読み込みを先に実行してください\n"); 126break; 127} 128else{ 129 int new_row = i+1; 130 printf("新しく追加するデータを入力してください\n"); 131 printf("それぞれ追加するデータを|名前,年齢,身長,体重|の形式で入力してください\n"); 132 // scanf("%c,%d,%d,%d",&new_name,&new_age,&new_height,&new_weight); 133 scanf("%c,%d,%d,%d",&Data[56].name,&Data[56].age,&Data[56].height,&Data[56].weight); 134 // scanf("\n年齢:%d",&Data[56].age); 135 // scanf("身長:%d",&Data[56].height); 136 // scanf("体重:%d",&Data[56].weight); 137 // Body Data[new_row] = {new_name,new_age,new_height,new_weight};//直近の行数+1配列目にデータを入れる 138} 139case 4: 140// 構造体配列の内容をファイルに書き出す 141// 参考:【B4】おまけ課題 50~59行目 142break; 143default: 144// プログラムを終了 145return 0; 146} 147} 148return 0; 149} 150// 関 数 の 定義 151// FIXME 152int is_loaded(int flag) 153{ 154 if (flag!=1){ 155 printf("\nファイル読み込みを先に実行してください\n"); 156 return -1; 157}else{ 158 // ファイル読み込みチェック完了 159 return 0; 160} 161} 162// 参考:【B4】おまけ課題 64行目以降 163//【B1】ステップ1 27~44行目 、【B2】ステップ2 52~63行目 164コード
「3.3さらに、追加で既存の配列+1(ここでは56番目などに)新規にデータを入れ込む方法です。
これがうまくいかないのでうまくいく方法があれば教えてほしいです。」とはどういうことでしょうか?
どんなコードを試してどんな結果(エラーなど)になったのでしょうか?
Body構造体のDataを定義してから
```c
printf("%s ファイルを開きました\n",fname);
// fread(fname,sizeof(char),10,fp);
printf("%s ファイルを読み込みました\n",fname);
for(i=0;i<MAXCNT;i++) {
if(fscanf(fp,"%s%d%d%d\n",
&Data[i].name,
&Data[i].age,
&Data[i].height,
&Data[i].weight) == EOF) break;
```
でsample.txtを読み込んだのですが、下記のcase3 にて新しいデータを追加したいです。
scanf("%c,%d,%d,%d",&Data[56].name,&Data[56].age,&Data[56].height,&Data[56].weight);
読みにくっ!すみません。。。

回答5件
あなたの回答
tips
プレビュー