- 締切済み
ファイル操作やポインタ、構造体について(C言語)
C言語の課題で詰まってしまいました。宜しければ助言を宜しくお願いします。 コマンド選択で,0) 終了,1) 追加,2) 検索(id),3)変更 が行える学生成績管理プログラムを作成する。 データは,学生の番号 名前 GP 総単位数 形で学生のデータを持っているファイルである。 #include<stdio.h> #include<stdlib.h> #include<string.h> struct student{ int id; char name[25]; int gp; int credit; }; void add(char *, struct student);//追加 int search(char *, struct student *);//検索 void change(char *, struct student);//指定したidの学生の情報を変更 main(int argc,char *argv[]) { FILE *fp; int i = 0; int num; struct student students; if(argc == 1){ printf("set filename\n"); return 1; } while(1) { printf("1)add 2)search 0)quit "); scanf("%d",&num); if(num == 0) break; /* 追加 */ if(num == 1) { printf("id name gp credit ? "); scanf("%d %s %d %d", &students.id, students.name, &students.gp, &students.credit); add(argv[1], students); } /* 検索 */ if(num == 2) { printf("id ? "); scanf("%d", &students.id); if(search(argv[1],&students)){ printf("%d %s %d %d\n", students.id, students.name, students.gp, students.credit); } else{ printf("ID %d Not Found.\n",students.id); } } if(num == 3){ //変更 } } } /* 追加ルーチン */ void add(char *filename, struct student students) { FILE *fp; if((fp = fopen(filename, "a")) == NULL){ printf("can't open %s\n", filename); exit(1); } fprintf(fp,"%d %s %d %d\n", students.id, students.name, students.gp, students.credit); fclose(fp); } /* 検索ルーチン */ int search(char *filename, struct student *students) { FILE *fp; int id; char name[25]; int gp; int credit; if((fp = fopen(filename, "r")) == NULL){ printf("can't open %s\n", filename); exit(1); } while(fscanf(fp,"%d %s %d %d", &id, name, &gp, &credit) != EOF) { if(id == students->id){ students->id = id; strcpy(students->name ,name); students->gp = gp; students->credit = credit; return 1; } } return 0; fclose(fp); } /* 変更ルーチン */ void add(char *filename, struct student students){ } ------------ここまで------------ ファイルの操作での入出力は"a"や"r"、また"w"を利用するのかとも思いましたが、 指定したIDの内容を書き換えるにはポインタを2つ使う方法しか思いつかないのですが、与えられた問題で、変更のプロトタイプは void change(char *, struct student); となっていて、どうやるのかまったく見当もつきません。 稚拙な文で伝わりにくいかもしれませんが、 変更のやり方についてご教授願います。 見難くて申し訳ありません。 どうか宜しくお願いします。
- みんなの回答 (4)
- 専門家の回答
みんなの回答
- crew21
- ベストアンサー率26% (58/222)
>指定したIDの内容を書き換えるにはポインタを2つ使う方法しか思いつかないのですが、... 要は、既に存在するファイル中に書き込まれている、誰か(検索ヒットした人)のIDを書き換えたい、ということだよね。 だとしたらポインタを2つどころか、一つもいらないと思うよ。 No.1さんが回答を書かれているので、詳細はNo.1さんのを参考にしてください。 --- あとこれは回答じゃないけど、なんつーのかな、悪いけどアナだらけのプログラムだぞ。いくら学生さんの課題とはいえ。 例えば、 scanf("%d %s %d %d", &students.id, students.name, &students.gp, &students.credit); で、25文字以上の学生名を入力された場合の処置(ガード)が無いよね。 もしそれやられたら一発でアウトだよ。その後に続くgpとかcreditを壊しちゃうからね。 それに、argv[1]はファイル名であることが前提とされてるけど、 せめてそれが本当に存在するファイルかどうかを確認するコードは入れた方がいいよ。 あと、小姑のようで悪いが、(argc == 1)のときに、set filename とモニタに表示されても、何だかイマイチわからんと思うがな..
- nuko_punch
- ベストアンサー率40% (10/25)
^^; スペルミスしてます。 ftellです。
- aris-wiz
- ベストアンサー率38% (96/252)
>fteel ftell ?
- nuko_punch
- ベストアンサー率40% (10/25)
"r+"でfopenすれば書き換え可能になりますよ。 current = fteel(fp); でファイル位置が分かります。 例)fseekでfscanfを行う前の位置に戻る。 current = fteel(fp); fscanf(fp,"%d %s %d %d", &id, name, &gp, &credit); fseek(fp, current, SEEK_SET); ただ、直接書き換える場合、色々と決まり事を作っておかないと、データを破壊する恐れがあります。 あとは試行錯誤してみてください。 ※ 細かいことは関数リファレンスを参照してください。