作成したプログラムファイルの管理を行うプログラムというものを学校の課題で行っているのですが、
この課題の制作にあたって、手始めにファイルの保存と読み込みを行う関数を作ろうと思うのですが、ファイルを保存する関数(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;
}
この回答への補足
回答ありがとうございます。参考にさせていただきましたが、
「collect2: ld はステータス 1 で終了しました」と出てコンパイルすることができません。いったいどうしてでしょうか。
使用しているOSはRED HAT ENTERPRISE LINUX 5、emacsで開発を行い、端末エミュレータを用いてコンパイルしています。
あの後にいろいろとご意見を参考にして、自分で調べたり人に聞いたりして解決することができました。ありがとうございます。
#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;
}
No.4
- 回答日時:
一応突っ込んでおくと,
scanf("%s",&file);
は
scanf("%s",file);
の方がよろしいかと>#2. あと, main にある const char * へのキャストはない方が自然でしょう.
後の大枠は #3 に同意. 「どのようにコンパイラを起動してどのようなメッセージが出たのか」を省略したりせず一字一句そのまま書いてください.
No.3
- 回答日時:
記載のソースはWindows XP上のVisual C++ 2008で動作確認しています。
とくに機種依存するような部分は無いと思いますが、Linux上のGCCでは環境条件を整える必要があるのかも知れません。
>「collect2: ld はステータス 1 で終了しました」
これはリンカのエラーですね。エラーの本体(どこでどんなエラーが起きてるのかという情報)はその前に出ているはずなので、それを示してもらわないとちょっと原因がわかりません。
返事が遅れてすみません。この問題については、nkf --overwrite -wでUFT-8に変換することで解決できました。ありがとうございます。
No.1
- 回答日時:
>ファイルを保存する関数(save)と読み込む関数(load)の作り方、ファイルポインタに格納する方法がわかりません。
バイナリファイルで構造体の中身を丸ごと読み書きする。
という方法もありましょう。
幸いにして構造体内にポインタはないようですので、それでも動作はするかと。
# ただし、書き出したファイルをテキストエディタなどで確認できませんが。
構造体のメンバを1行1メンバとして読み書きする(int型の日付に関しては数値<>数字変換を行う)という方法もあるでしょう。
「ファイルポインタに格納する」の意味が不明ですが。
あと、掲示されている例ではload()は期待する動作をできないでしょう。
呼び出し元からstruct recordのポインタを渡してもらって、そこに格納するべきです。
# scanf()で渡す場合と同様です。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- C言語・C++・C# プログラミング c言語 4 2023/03/07 01:05
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# C言語(構造体) 3 2022/07/05 20:08
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
複数ファイルの同時読み込みの...
-
C言語にてXMLファイルから任意...
-
fopenでファイル名に、変数を使...
-
C言語でファイル名を変数にした...
-
C言語でファイル読み書きを早く...
-
CRC32の計算方法
-
fscanfでループしてしまう。
-
CSVファイルの内容を構造体に格...
-
commons-netでのFTP送信について
-
ファイルに行番号を追加
-
【C言語】ファイルを読み込んで...
-
csvファイルの読み込みで失敗し...
-
c言語でのfscanfについて
-
C++で、先頭に同じ文字列がある...
-
txtファイルの文字を配列に格納
-
同時にファイル読み込み 書き込み
-
[C言語]2つのファイルを用いた...
-
C言語のファイル操作についての...
-
c言語 文字数のカウント 合わ...
-
テキストファイルをバイナリフ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ガンマ変換 C言語でプログラ...
-
c言語でのfscanfについて
-
なぜCSQとCIP形式ではコ...
-
複数ファイルの同時読み込みの...
-
fopenでファイル名に、変数を使...
-
ファイル出力で改行を入れたい!
-
ファイルへの書込み処理が異常...
-
【C言語】ファイルを読み込んで...
-
エラーがわかりません、、
-
C言語でセグメンテーションエ...
-
C言語でファイル読み書きを早く...
-
テキストファイル内に対して, ...
-
fgets( ) の返り値は何?
-
ファイルに行番号を追加
-
OpenGLによる描画内容をBMP出力
-
fscanfでループしてしまう。
-
c言語 ファイルから数字を読み...
-
ファイルが読み込めない・・・
-
CRC32の計算方法
-
CSVファイルの内容を構造体に格...
おすすめ情報