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

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

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

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

Q&A

解決済

1回答

472閲覧

入力した学籍番号とファイル読み込みした学籍番号が重複した場合に上書きするようにしたい。

P_Beginner

総合スコア99

C

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

0グッド

1クリップ

投稿2018/01/15 11:26

上書きする方法を考えて見たのですが、以下の2通りを考えました。
1.ファイル読み込み繰り返し時に毎回重複していないか判断し、重複していたら読み込まない。
2.一度全てファイル読み込みし、重複を探し重複があったら削除。

このときのどちらかを組み込みたいです。

考えたプログラムコードは上の1番で、file_read関数部のwhile文を
check関数の一部を書き換えたif(strcmp(number,(std+i)->number) != 0)で囲ってみることにしたのですが(エラーになった)、検索をするわけではないのでnumberの部分が変わるのでしょうか?
それとも考え方が間違っているのでしょうか?

C言語

1#include<stdio.h> 2#include<string.h> 3#include<stdlib.h> 4 5struct student{ 6 char number[10]; //学籍番号 7 char name[50]; //氏名 8}; 9 10void data_in(struct student *std); //入力 11void data_out(struct student *std); //出力 12void data_asc(struct student *std,int ninzu); //昇順 13void data_desc(struct student *std,int ninzu); //降順 14int data_delete(struct student *std,int ninzu,int search); //削除 15int file_read(struct student *std,int ninzu); //読み込み 16void file_write(struct student *std,int ninzu); //書き込み 17int check(struct student *std,int ninzu); //検索 18 19int main(void) 20{ 21 struct student std[22]; //生徒人数 22 int ninzu=0,i,search; //n:人数(データ数), i:繰り返し用, search:検索配列値格納用 23 int menu,end=0; //menu:処理選択用, end:終了用 24 25 while(1) 26 { 27 printf("メニュー\n"); 28 printf("1:データ入力\n"); 29 printf("2:データ出力\n"); 30 printf("3:小さい順に整列\n"); 31 printf("4:大きい順に整列\n"); 32 printf("5:データ削除\n"); 33 printf("6:ファイルからデータ読み込み\n"); 34 printf("7:ファイルへのデータ書き込み\n"); 35 printf("8:データ検索\n"); 36 printf("9:終了\n"); 37 printf("実行する処理の番号-->"); 38 scanf("%d%*c", &menu); //%*c:改行を読み飛ばす 39 40 switch(menu) 41 { 42 case 1: //入力 43 if(ninzu>=22){ //既に22名のデータが存在する時 44 printf("データ数が上限に達しています\n\n"); 45 break; 46 } 47 data_in(&std[ninzu]); 48 ninzu++; //人数を1人分増やす 49 printf("\n"); 50 break; 51 case 2: //表示 52 for(i=0;i<ninzu;i++) //入力した人数分 53 data_out(&std[i]); 54 if(ninzu==0) //データが存在しない時 55 printf("表示するデータがありません\n"); 56 printf("\n"); 57 break; 58 case 3: //昇順ソート 59 if(ninzu==0){ //データが存在しない時 60 printf("整列させるデータが存在しません\n\n"); 61 break; 62 } 63 data_asc(&std[0],ninzu); 64 break; 65 case 4: //降順ソート 66 if(ninzu==0){ //データが存在しない時 67 printf("整列させるデータが存在しません\n\n"); 68 break; 69 } 70 data_desc(&std[0],ninzu); 71 break; 72 case 5: //削除 73 search=check(&std[0],ninzu); //検索した値の配列の中身を格納 74 if(search>=0){ //検索したデータと同じデータが見つかった場合 75 data_out(&std[search]); 76 ninzu=data_delete(&std[0],ninzu,search); 77 printf("上記のデータを削除しました\n\n"); 78 } 79 else{ 80 printf("データが存在しません\n\n"); 81 } 82 break; 83 case 6: //ファイル読み込み 84 ninzu=file_read(&std[0],ninzu); //読み込んだ時のデータ数を格納 85 break; 86 case 7: //ファイル書き込み 87 if(ninzu==0){ //データが存在しない時 88 printf("書き込むデータが存在しません\n\n"); 89 break; 90 } 91 file_write(&std[0],ninzu); 92 break; 93 case 8: //検索 94 search=check(&std[0],ninzu); //検索した値の配列の中身を格納 95 if(search>=0){ //検索したデータと同じデータが見つかった場合 96 printf("検索結果\n"); 97 data_out(&std[search]); 98 printf("\n"); 99 } 100 else{ 101 printf("データが存在しません\n\n"); 102 } 103 break; 104 case 9: //終了 105 end=1; //終了条件の値を代入 106 break; 107 default: //エラー 108 printf("入力番号がありません\n\n"); 109 } 110 if(end==1) //終了条件の値が入っている時 111 break; 112 } 113 return 0; 114} 115void data_in(struct student *std) //入力 116{ 117 printf("学籍番号---->"); 118 gets(std->number); //学籍番号のデータ読み込み 119 printf("名前---->"); 120 gets(std->name); //氏名のデータ読み込み 121} 122void data_out(struct student *std) //出力 123{ 124 printf("%s\t%s\n", std->number, std->name); //既存のデータ表示 125} 126void data_asc(struct student *std,int ninzu) //昇順 127{ 128 int i,j; 129 struct student temp; 130 131 //学籍番号を昇順にソート 132 for(i=0;i<ninzu;i++){ //i番目のカウント 133 for(j=i;j<ninzu;j++){ //j番目のカウント 134 if(strcmp((std+i)->number,(std+j)->number)>0){ //i番目の方が大きい時 135 temp=*(std+i); //i番目のデータを退避 136 *(std+i)=*(std+j); //j番目のデータを格納 137 *(std+j)=temp; //i番目のデータを格納 138 } 139 } 140 } 141 142 printf("小さい順に並べかえました\n\n"); 143} 144void data_desc(struct student *std,int ninzu) //降順 145{ 146 int i,j; 147 struct student temp; 148 149 //学籍番号を降順にソート 150 for(i=0;i<ninzu;i++){ //i番目のカウント 151 for(j=i;j<ninzu;j++){ //j番目のカウント 152 if(strcmp((std+i)->number, (std+j)->number)<0){ //i番目の方が小さい時 153 temp=*(std+i); //i番目のデータを退避 154 *(std+i)=*(std+j); //j番目のデータを格納 155 *(std+j)=temp; //i番目のデータを格納 156 } 157 } 158 } 159 160 printf("大きい順に並べかえました\n\n"); 161} 162int data_delete(struct student *std,int ninzu,int search) //削除 163{ 164 int i; 165 166 for(i=search;i<ninzu;i++){ //検索した位置から人数を最後尾まで 167 std[i]=std[i+1]; //削除してできた空き要素を詰める 168 } 169 ninzu--; //削除した分の人数を減ずる 170 171 return ninzu; //人数をmain関数に返す 172} 173int file_read(struct student *std,int ninzu) //読み込み 174{ 175 FILE *fin; 176 char in_filename[20]; 177 int i=0; 178 179 printf("入力ファイル名---->"); 180 gets(in_filename); //ファイル名の読み込み 181 182 if((fin = fopen(in_filename,"r")) == NULL){ //ファイルが開けない時 183 printf("ファイルが開けません\n\n"); 184 return ninzu; //人数をmain関数に返す 185 } 186 while(fscanf(fin,"%s\t%s",(std+ninzu)->number,(std+ninzu)->name) != EOF){ //ファイルのデータを読み込む 187 ninzu++; //読み込んだ人数を増やす 188 i++; //ファイルのデータ数をカウント 189 } 190 191 if(i==0) 192 printf("ファイルにデータが存在しません\n\n"); 193 else 194 printf("ファイルを読み込みました\n\n"); 195 196 fclose(fin); //ファイルを閉じる 197 198 return ninzu; 199} 200void file_write(struct student *std,int ninzu) //書き込み 201{ 202 FILE *fout; 203 char out_filename[20]; 204 int i; 205 206 printf("出力ファイル名---->"); 207 gets(out_filename); //ファイル名の読み込み 208 209 if((fout = fopen(out_filename, "w")) == NULL){ //書き込み用ファイルを開けなかった時 210 printf("ファイルが開けません\n"); 211 fclose(fout); //ファイルを閉じる 212 } 213 214 for(i=0;i<ninzu;i++){ //人数分 215 fprintf(fout,"%s\t%s\n",(std+i)->number,(std+i)->name); //ファイルへ書き込む 216 } 217 218 printf("ファイルへ書き込みました\n\n"); 219 220 fclose(fout); //ファイルを閉じる 221} 222 223int check(struct student *std,int ninzu) //検索 224{ 225 char number[10]; 226 int i; 227 228 if(ninzu>0){ //データが存在する時 229 printf("学籍番号を入力---->"); 230 gets(number); 231 for(i=0;i<ninzu;i++){ //人数分のデータを順番に 232 if(strcmp(number,(std+i)->number) == 0) //一致する文字列(学籍番号)があった時 233 return i; //データの位置をmain関数に返す 234 } 235 } 236 237 return -1; //見つけられなかったときに返す 238} 239 240 241

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

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

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

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

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

Zuishin

2018/01/15 12:00

前の質問をほったらかしにして次々と新しい質問をするものではありません。コメントには何らかの返信をし、解決したらベストアンサーを決め、解決しない場合はその旨伝え、自力で解決した場合には自己解決にしましょう。
guest

回答1

0

ベストアンサー

どのような運用をするか書いていないので憶測ですが、おそらく次のような手順で処理するものと思われます。
すでに何件かのデータがファイルに登録されている状態で、
0. 読み込み
0. 入力(重複なし)
0. 入力(重複あり)

このとき3の処理をどうするか、かと思われます。
入力処理自体はあくまでも読み込み済みのデータに追加・上書きをすることになるので、ファイルを読み込んで云々はまったく不要。
なので入力処理を次のような流れにしてみてはいかがでしょうか。

  1. 学籍番号入力
  2. 登録済みかチェック(登録済みの場合、配列位置を取得)
  3. 登録済みの場合、上書きするか中止するかを問い合わせる
  4. 氏名入力
  5. 登録済みの場合、1の配列位置に氏名を登録
  6. 登録済みではない場合、空き要素に学籍番号・氏名を登録

3は勝手に考えた仕様なので、質問者様が決めてください(登録済みの場合は上書き禁止など)

投稿2018/01/16 01:06

ttyp03

総合スコア16998

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問