- ベストアンサー
作成したプログラムファイルの管理を行うプログラムとは?
- 作成したプログラムファイルの管理を行うプログラムとは学校の課題であり、ファイルの保存と読み込みを行う関数を作成する際には、ファイルを保存する関数(save)やファイルを読み込む関数(load)の作り方、ファイルポインタへの格納方法が必要です。
- プログラムファイル管理プログラムではファイルの保存や読み込みを行うための関数を作成する必要があります。ファイルの保存を行う関数(save)では、ファイルポインタを使ってファイルを開き、ファイルにデータを書き込む処理を行います。一方、ファイルの読み込みを行う関数(load)では、ファイルポインタを使ってファイルを開き、ファイルからデータを読み込む処理を行います。
- 作成したプログラムファイルの管理を行うプログラムは、学校の課題であり、ファイルの保存と読み込みを行う関数を作成する必要があります。ファイルの保存を行う関数(save)では、ファイルポインタを使ってファイルを開き、指定したデータをファイルに書き込む処理を行います。一方、ファイルの読み込みを行う関数(load)では、ファイルポインタを使ってファイルを開き、ファイルからデータを読み込む処理を行います。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
テキストで保存する方法を考えたけど、あまり良くない。(スペースが含まれてるとfscanfはそこで区切ってしまい、以降は正常に読めなくなる) これを防ぐにはそれなりの処理を考える必要があるけど、面倒ならバイナリで構造体ごと保存・読み込みをした方が楽。 それにしても、元のソースは誤りが多い。 main関数内をどう直したかぐらいはチェックしてほしい。 #include <stdio.h> struct date {/*作成日付を格納*/ int year;/*年*/ int month;/*月*/ int day;/*日*/ }; struct record {/*レコード*/ char title[30];/*タイトル名*/ char stitle[50];/*副タイトル名*/ struct date adate;/*作成日付*/ char path[50];/*パス名(ファイルがどこのフォルダにあるか)*/ char category[30];/*分類*/ }; int save(struct record data, const char *fname)/*ファイルを保存する*/ { FILE *fp; fp = fopen(fname,"w"); if (fp == NULL){ fprintf(stderr,"Cannot open file: %s\n", fname); return -1; } fprintf(fp, "title=%s\n", data.title); fprintf(fp, "stitle=%s\n", data.stitle); fprintf(fp, "date=%04d-%02d-%02d\n", data.adate.year, data.adate.month, data.adate.day); fprintf(fp, "path=%s\n", data.path); fprintf(fp, "category=%s\n", data.category); fclose(fp); return(0); } int load(struct record *pdata, const char *fname)/*ファイルを読み込む*/ { FILE *fp; fp = fopen(fname,"r"); if (fp == NULL){ fprintf(stderr,"Cannot open file: %s\n", fname); return -1; } fscanf(fp, "title=%s\n", pdata->title); fscanf(fp, "stitle=%s\n", pdata->stitle); fscanf(fp, "date=%04d-%02d-%02d\n", &(pdata->adate.year), &(pdata->adate.month), &(pdata->adate.day)); fscanf(fp, "path=%s\n", pdata->path); fscanf(fp, "category=%s\n", pdata->category); fclose(fp); return(0); } int main(void) { int num; char file[256]; int sortnum; struct record recdata; printf("プログラムファイル管理プログラムへようこそ!\n"); do{ printf("何をしますか?\n"); printf("[0:終了、1:保存、2:読み込み]\n"); printf("入力してください: "); scanf("%d",&num); if(num==1 || num == 2){ printf("ファイル名を指定してください: "); scanf("%s",&file); if(num==1) save(recdata, (const char *)file); if(num==2) load(&recdata, (const char *)file); }else if (num != 0) { printf("入力された数値が正しくありません。\n"); } }while(num != 0); return 0; }
その他の回答 (3)
- Tacosan
- ベストアンサー率23% (3656/15482)
一応突っ込んでおくと, scanf("%s",&file); は scanf("%s",file); の方がよろしいかと>#2. あと, main にある const char * へのキャストはない方が自然でしょう. 後の大枠は #3 に同意. 「どのようにコンパイラを起動してどのようなメッセージが出たのか」を省略したりせず一字一句そのまま書いてください.
お礼
なるほど。回答ありがとうございます。
- magicalpass
- ベストアンサー率58% (378/648)
記載のソースはWindows XP上のVisual C++ 2008で動作確認しています。 とくに機種依存するような部分は無いと思いますが、Linux上のGCCでは環境条件を整える必要があるのかも知れません。 >「collect2: ld はステータス 1 で終了しました」 これはリンカのエラーですね。エラーの本体(どこでどんなエラーが起きてるのかという情報)はその前に出ているはずなので、それを示してもらわないとちょっと原因がわかりません。
お礼
返事が遅れてすみません。この問題については、nkf --overwrite -wでUFT-8に変換することで解決できました。ありがとうございます。
- Wr5
- ベストアンサー率53% (2173/4061)
>ファイルを保存する関数(save)と読み込む関数(load)の作り方、ファイルポインタに格納する方法がわかりません。 バイナリファイルで構造体の中身を丸ごと読み書きする。 という方法もありましょう。 幸いにして構造体内にポインタはないようですので、それでも動作はするかと。 # ただし、書き出したファイルをテキストエディタなどで確認できませんが。 構造体のメンバを1行1メンバとして読み書きする(int型の日付に関しては数値<>数字変換を行う)という方法もあるでしょう。 「ファイルポインタに格納する」の意味が不明ですが。 あと、掲示されている例ではload()は期待する動作をできないでしょう。 呼び出し元からstruct recordのポインタを渡してもらって、そこに格納するべきです。 # scanf()で渡す場合と同様です。
お礼
回答ありがとうございます。
お礼
あの後にいろいろとご意見を参考にして、自分で調べたり人に聞いたりして解決することができました。ありがとうございます。 #include <stdio.h> #include <stdlib.h> #include <string.h> #define BUFSIZE 128 #define DATASIZE 1000 typedef struct record { char title[50]; char stitle[100]; char date[16]; char path[200]; char category[50]; } record; record *head; record header; int record_counter = 0; record ad[DATASIZE]; int main() { char dummy[BUFSIZE]; int i,cnt = 0; puts("*Program Application*"); while(1){ puts("何をしますか?"); printf("0:終了\n1:検索\n2:追加\n3:修正\n4:削除\n5:全体\n6:ソート\n7:ファイルに書き込み\n8:ファイルから読み込み\n入力してください:");/*それぞれの関数をプロトタイプ宣言で呼び出す、省略*/ scanf("%d",&i); gets(dummy); if(1 <= i && i <= 8) cnt = func[i - 1](ad,cnt); else if(i != 0) printf("Error!\n"); else if(i == 0) break; } return 0; } int write(record *ap,int cnt) { FILE *fp; record *t; int check = 0; fp = fopen("record_management.dat","w"); if(fp == NULL){ fprintf(stderr,"Cannot open file."); return -1; } for(check = 0;check < cnt;check++) { fprintf(fp,"%d\n",check + 1); fprintf(fp,"%s\t\n",ap[check].title); fprintf(fp,"%s\t\n",ap[check].stitle); fprintf(fp,"%s\t\n",ap[check].date); fprintf(fp,"%s\t\n",ap[check].path); fprintf(fp,"%s\t\n",ap[check].category); t = ap + cnt; } fclose(fp); puts("書き込みが完了しました。\n"); return cnt; } int read(record *ap,int cnt) { FILE *fp; record *t = ap; if((fp = fopen("record_management.dat","r"))==NULL){ fprintf(stderr,"Cannot open file.\n"); return -1; } while(fscanf(fp,"%d",&cnt) != EOF) { fscanf(fp,"%s\t",t->title); fscanf(fp,"%s\t",t->stitle); fscanf(fp,"%s\t",t->date); fscanf(fp,"%s\t",t->path); fscanf(fp,"%s\t",t->category); t = ap + cnt; } fclose(fp); return cnt; }
補足
回答ありがとうございます。参考にさせていただきましたが、 「collect2: ld はステータス 1 で終了しました」と出てコンパイルすることができません。いったいどうしてでしょうか。 使用しているOSはRED HAT ENTERPRISE LINUX 5、emacsで開発を行い、端末エミュレータを用いてコンパイルしています。