作成したプログラムファイルの管理を行うプログラムとは?

このQ&Aのポイント
  • 作成したプログラムファイルの管理を行うプログラムとは学校の課題であり、ファイルの保存と読み込みを行う関数を作成する際には、ファイルを保存する関数(save)やファイルを読み込む関数(load)の作り方、ファイルポインタへの格納方法が必要です。
  • プログラムファイル管理プログラムではファイルの保存や読み込みを行うための関数を作成する必要があります。ファイルの保存を行う関数(save)では、ファイルポインタを使ってファイルを開き、ファイルにデータを書き込む処理を行います。一方、ファイルの読み込みを行う関数(load)では、ファイルポインタを使ってファイルを開き、ファイルからデータを読み込む処理を行います。
  • 作成したプログラムファイルの管理を行うプログラムは、学校の課題であり、ファイルの保存と読み込みを行う関数を作成する必要があります。ファイルの保存を行う関数(save)では、ファイルポインタを使ってファイルを開き、指定したデータをファイルに書き込む処理を行います。一方、ファイルの読み込みを行う関数(load)では、ファイルポインタを使ってファイルを開き、ファイルからデータを読み込む処理を行います。
回答を見る
  • ベストアンサー

作成したプログラムファイルの管理を行うプログラムというものを学校の課題

作成したプログラムファイルの管理を行うプログラムというものを学校の課題で行っているのですが、 この課題の制作にあたって、手始めにファイルの保存と読み込みを行う関数を作ろうと思うのですが、ファイルを保存する関数(save)と読み込む関数(load)の作り方、ファイルポインタに格納する方法がわかりません。 現在の途中経過を示します。 #include <stdio.h> #include <stdlib.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 file)/*ファイルを保存する*/ { FILE *fp; int c; fp = fopen("program.txt","w"); if (fp == NULL){ fprintf(stderr,"Cannot open file: composition.txt\n"); return -1; } fprintf(""); fclose(fp); } int load(struct record file)/*ファイルを読み込む*/ { } int main() { int num; char file; int sortnum; 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(file); if(num==2) load(file); }else printf("入力された数値が正しくありません。\n"); }while(num != 0) return 0; }

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

テキストで保存する方法を考えたけど、あまり良くない。(スペースが含まれてると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; }

suzukiaen
質問者

お礼

あの後にいろいろとご意見を参考にして、自分で調べたり人に聞いたりして解決することができました。ありがとうございます。 #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; }

suzukiaen
質問者

補足

回答ありがとうございます。参考にさせていただきましたが、 「collect2: ld はステータス 1 で終了しました」と出てコンパイルすることができません。いったいどうしてでしょうか。 使用しているOSはRED HAT ENTERPRISE LINUX 5、emacsで開発を行い、端末エミュレータを用いてコンパイルしています。

その他の回答 (3)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.4

一応突っ込んでおくと, scanf("%s",&file); は scanf("%s",file); の方がよろしいかと>#2. あと, main にある const char * へのキャストはない方が自然でしょう. 後の大枠は #3 に同意. 「どのようにコンパイラを起動してどのようなメッセージが出たのか」を省略したりせず一字一句そのまま書いてください.

suzukiaen
質問者

お礼

なるほど。回答ありがとうございます。

回答No.3

記載のソースはWindows XP上のVisual C++ 2008で動作確認しています。 とくに機種依存するような部分は無いと思いますが、Linux上のGCCでは環境条件を整える必要があるのかも知れません。 >「collect2: ld はステータス 1 で終了しました」 これはリンカのエラーですね。エラーの本体(どこでどんなエラーが起きてるのかという情報)はその前に出ているはずなので、それを示してもらわないとちょっと原因がわかりません。

suzukiaen
質問者

お礼

返事が遅れてすみません。この問題については、nkf --overwrite -wでUFT-8に変換することで解決できました。ありがとうございます。

  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.1

>ファイルを保存する関数(save)と読み込む関数(load)の作り方、ファイルポインタに格納する方法がわかりません。 バイナリファイルで構造体の中身を丸ごと読み書きする。 という方法もありましょう。 幸いにして構造体内にポインタはないようですので、それでも動作はするかと。 # ただし、書き出したファイルをテキストエディタなどで確認できませんが。 構造体のメンバを1行1メンバとして読み書きする(int型の日付に関しては数値<>数字変換を行う)という方法もあるでしょう。 「ファイルポインタに格納する」の意味が不明ですが。 あと、掲示されている例ではload()は期待する動作をできないでしょう。 呼び出し元からstruct recordのポインタを渡してもらって、そこに格納するべきです。 # scanf()で渡す場合と同様です。

suzukiaen
質問者

お礼

回答ありがとうございます。

関連するQ&A

  • ファイル操作やポインタ、構造体について(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); となっていて、どうやるのかまったく見当もつきません。 稚拙な文で伝わりにくいかもしれませんが、 変更のやり方についてご教授願います。 見難くて申し訳ありません。 どうか宜しくお願いします。

  • csvファイルの実績データをC言語で解析するのですが...

    C言語を学び始めたばかりなのに、csvファイルの実績データでフィールドが15あり、レコード数が1000000近くあるファイルの15番目のフィールドを足し合わせて、出力するということをやっているのですが、まだまだわからないことだらけです。 1レコード目がカラム名なので2レコード目から足し合わせるんですがそこのところもよくわからずじまいで... 一応、書いたプログラムが #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { FILE *fp; char buffer[50],*p; int cnt, num, sum; fp = fopen("j0.csv","r"); if(fp == NULL){ printf("ファイルが開けませんでした。\n"); exit(-1); } while(fgets(buffer,fp) != NULL){ p = strtok(buffer,","); cnt = 1; while(p!=NULL){ num = atoi(p); printf("%d:%d,",cnt,num); p = strtok(NULL,","); cnt++; if(cnt==15) sum=sum+num } printf("\b\b \n"); } printf(%d \n",num); fclose(fp); return(0); } と書いたんですが、ぜんぜんな状態です。誰かご教授願えませんか?

  • ファイルから一文字ずつ読み込む

    ファイルを読み込むfgetc()関数のところでプログラムが停止します。 以下が実行したプログラムです。 #include<stdio.h> void get_name(char name[],int a){ printf("ファイル名を入力してください。\n"); scanf("%s",name); } void open(FILE *fp2,char name[]){ if((fp2=fopen(name,"r"))==NULL){ printf("ファイルオープンエラー"); } } int count(FILE *fp3){ int ch=0; int count=0; if(fp3==NULL){ printf("error"); } while((ch=fgetc(fp3))!=EOF){ if(ch=='\n'){ count++; } } printf("TEST"); fclose(fp3); return(count); } int main (void){ FILE *fp; char fname[30]; get_name(fname,30); open(fp,fname); printf("%d",count(fp)); return(0);} ファイル名を入力してください。ファイル名を入力、プログラム停止です。 '\n'を数えれるようにしてください。御指摘お願いします。

  • プログラムの異常終了

    TEST2とコマンドプロンプトに表示された後、異常終了します。 以下が実行したプログラムです。 #include<stdio.h> void get_name(char **f_name2){ printf("ファイル名を入力"); scanf("%s",*f_name2); } int count_num(FILE *fp){ int ch =0; int count=0; while((ch=fgetc(fp))!=EOF){ if(ch>0&&ch<9){ count++; } } return(count); } int main (void){ char *fname; FILE *fp; get_name(&fname); if((fp=fopen(fname,"r"))==NULL){ printf("ファイルオープンエラー"); }else{ printf("%d\n",count_num(fp)); } fclose(fp); printf("TEST2\n"); return(0); } textc13-7.exeは動作を停止しました。と表示があります。正常に終了したいので、 御指摘お願いします。

  • プログラムの実行

    このプログラム(下)なんですが、実行はできますが、実行結果が自分が思っているのとは異なる結果がでてしまいます。 'database.txt'には、1~100までの半角数字で入力した数字が1あがるごとに改行して保存しています。 僕は、例えばこのプログラムで2を入力すると、「一致しました」と表示されて、登録されていない数字345とかを入力すると「検索されませんでした」と表示されるようにしたいのですが、適当な数字を入れても「一致しました」と表示される場合があるのでこれを改善する方法を教えてください。 #define FNAME "database.txt" #define RECORDLEN 88 #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { FILE *fp; char search[8],num[2]; int no = 0, find = 0, ip; fp = fopen(FNAME, "r"); if (fp == NULL) { perror("ファイルがオープンできません\n"); return -1; } printf("検索する番号の入力-- "); gets(search); while (1) { fseek(fp, RECORDLEN * no++, SEEK_SET); if (fscanf(fp, "%s", num) == EOF) break; if (strstr(num, search) != NULL) { find++; fscanf(fp, "%d", &ip); printf("番号結果: %d\n", ip); break; } } if(find==0){ printf("検索されませんでした\n"); } else{ printf("一致しました。\n"); } fclose(fp); return 0; }

  • 1000000レコードもあるcsvファイルの実績データをC言語で計算しているのですが...

    C言語を学び始めたばかりなのに、csvファイルの実績データでフィールドが15あり、レコード数が1000000近くあるファイルの15番目のフィールドを足し合わせて、出力するということをやっているのですが、まだまだわからないことだらけです。 一応、書いたプログラムが #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { FILE *fp; char buffer[50],*p; int cnt, num, sum; fp = fopen("j0.csv","r"); if(fp == NULL){ printf("ファイルが開けませんでした。\n"); exit(-1); } while(fgets(buffer,fp) != NULL){ p = strtok(buffer,","); cnt = 1; while(p!=NULL){ num = atoi(p); printf("%d:%d,",cnt,num); p = strtok(NULL,","); cnt++; if(cnt==15) sum=sum+num } printf("\b\b \n"); } printf(%d \n",num); fclose(fp); return(0); } と書いたんですが、ぜんぜんな状態です。誰かご教授願えませんか?

  • データ管理プログラムを作っているんですが、初心者なもので困っています…。

    学校の課題で上手くいかずに困っています。キーボードから入力したものを構造体に納める機能を関数で実装するんですが、1番目の構造体に入力した後、次の構造体に入力できません。下にその関数の部分を載せるので、どのように直したらいいか、また上手くいかなかった原因を教えてくだい。 typedef struct _Music { char title[1024]; char artist[1024]; int year, month, day, star; } Music; void register_record(Music *mus, int *current_num_ptr); int main(void) { Music musiclist[200]; int num_record = 0; char buf[128], n; while (1) { printf("[1]Registration [q|Q]quit\nEnter Number> "); fgets(buf, sizeof(buf), stdin); sscanf(buf, "%c", &n); if (n == 'q' || n == 'Q') { break; } else if (n == '1') { printf("Registration\n"); register_record(musiclist, &num_record); num_record = num_record + 1; } else { printf("wrong number\n"); } } return 0; } void register_record(Music *mus, int *current_num_ptr) { char tem[1024]; int x; printf("Title> "); scanf("%s", tem); strcpy(mus->title, tem); printf("Artist> "); scanf("%s", tem); strcpy(mus->artist, tem); printf("Date(year)> "); scanf("%d", &x); mus->year = x; printf("Date(month)> "); scanf("%d", &x); mus->month = x; printf("Date(day)> "); scanf("%d", &x); mus->day = x; printf("My Rate> "); scanf("%d", &x); mus->star = x; printf("---Complete registration!!---\n"); printf("No.%d Title:%s Artist:%s Date:%d/%d/%d My Rate:%d\n", current_num_ptr, mus->title, mus->artist, mus->year, mus->month, mus->day, mus->star); }

  • C言語 Segmentation fault

    program SPROGRAM 17 4 pas104 SIDENTIFIER 43 4 ( SLPAREN 33 4 上記のようなファイルを読みこんで、1行づつ各トークン(programとか17とか)を構造体に格納する関数reader()を作りましたが、これを以下のparser.cで呼びだすと「Segmentation fault(core dumped)」となってしまいます。gdbのrunコマンドでプログラムを実行すると、関数を呼び出す所で Program received signal SIGSEGV, Segmentation fault. 0x0040140f in reader () と表示されました。が,どうすればよいか全然分かりません・・・ どうすれば正しく動作してくれるのか、どなたか教えてください・・・ 以下ソース /*read.c*/ #include "head.h" void reader(void) { fprintf(stdout,"check"); char buf[BUF_LEN]; if (fgets(buf,sizeof(buf),fp) == NULL)/*ここで1行読みこむ*/ {/*いきなりNULLの場合*/ strcpy(t.str, ""); t.num = SEOF; t.line = 1; } else { 省略 } return; } /*parser.c*/ #include "head.h" struct tokenbox t; FILE *fp; int main(int argc, char *argv[]) { if (argc != 2)/*引数チェック*/ { fprintf(stderr,"Usage: (./parser) (file.ts)\n"); return -1; } int len; len = strlen(argv[1]);/*file.ts の長さ取得*/ if((argv[1][len-1] == 's') && (argv[1][len-2] =='t') && (argv[1][len-3] == '.'))/*tsファイルが指定されているかどうか*/ { fp = fopen(argv[1],"r");/*ファイルオープン*/ if (fp == NULL) { fprintf(stderr,"Such ts file is not exist\n"); return -1; } fprintf(stdout,"authenticate ts file!\n");//←これは出力される reader(); //←ここでSegmentation faultと思われる printf("t.str = %s\n", t.str); printf("t.str[0] = %c\n", t.str[0]); printf("t.num = %d\n", t.num); printf("t.line = %d\n", t.line); fclose(fp); return 0; } else { fprintf(stderr,"the file is not ts\n"); return -1; } } ヘッダファイル一部抜粋 /*head.h*/ #include <stdio.h> #include <string.h> #include <stdbool.h> #define BUF_LEN 128 #define TOKEN_LEN 128 struct tokenbox {/*tsファイルの各情報を格納する構造体*/ char str[TOKEN_LEN]; int num; int line; }; extern struct tokenbox t;/*構造体をtと置く*/ extern FILE *fp; /*ファイルポインタ*/

  • C言語で、ファイルを読み込んで数字と名前に分けて配列に格納に関する質問

    C言語で、ファイルを読み込んで数字と名前に分けて配列に格納に関する質問です! ファイルを開いた後でエラーとなるのですが、何が足りないのでしょうか? ファイル内容 20 田中 10 鈴木 #include <stdio.h> #include <string.h> #include <stdlib.h> int main(int argc,char *argv[]) { FILE *fp; char str[256]; char *tp; int k,i=0; int num[10]; char na[10][20]; fp=fopen(argv[1],"r"); if(fp==NULL){ printf("ファイルを開けません\n"); return 1; }else{ printf("開けた\n"); } while(fgets(str,sizeof str,fp)!=NULL){ tp=strtok(str," "); num[i]=atoi(tp); tp=strtok(NULL," "); strcpy(na[i],tp); i++; } printf("%d\n%s\n",num[0],na[0]); printf("%d\n%s\n",num[1],na[1]); fclose(fp); return 0; }

  • 任意のファイルを別のファイルにコピーするプログラム。

    コマンドラインからコピー元、コピー先ファイル名を指定してファイルをコピーするプログラムなんですが… #include <stdio.h> #include <stdlib.h> main(int argc, char *argv[]) { FILE *fp; if ((fp = fopen(argv[0],"r") == NULL){ printf("ファイル%sが存在しません。\n",argv[0]);exit(-1); } if ((fp = fopen(argv[1],"w") == NULL){ printf("ファイル%sがコピーできません。\n",argv[1]);exit(-1); } fclose(fp); } どこか間違っているところがあるでしょうか? ありましたら詳しく教えてもらえると幸いです。 少し自信がないのでわかる方はよろしくおねがいします。

専門家に質問してみよう