C言語の構造体のファイルへの書き込みについて

このQ&Aのポイント
  • C言語を勉強しているものです。構造体を指定した番号の場所にファイルへ書き出し、その指定した番号の場所の構造体をファイルから読み込み表示というプログラムを作成したいのですが、うまくいかずどうしたらいいのかわかりません。
  • 説明不足ですがご教授お願いします。ソフトはVisual C++ 2008 Express Editionを使ってます。
  • 構造体のファイルへの書き込みと読み込みがうまくできない問題で困っています。ご教授お願いします。
回答を見る
  • ベストアンサー

C言語の構造体のファイルへの書き込みについて

C言語を勉強しているものです。構造体を指定した番号の場所にファイルへ書き出し、その指定した番号の場所の構造体をファイルから読み込み表示というプログラムを作成したいのですが、うまくいかずどうしたらいいのかわかりません。説明不足ですがご教授お願いします。 ソフトはVisual C++ 2008 Express Editionを使ってます。 ↓↓↓作成ソースコード↓↓↓ #include<stdio.h> #include<stdlib.h> struct S_data{ char Name[10+1];/*名前*/ int Sex;/*性別*/ int Height;/*身長*/ float Weight;/*体重*/ }; void main(){ FILE *Fp; int pos; int Ret; struct S_data tag; memset(&tag,'\0',sizeof(tag)); Fp=fopen("aaa.dat","r+b"); if(Fp==NULL){ Fp=fopen("aaa.dat","w+b"); if(Fp==NULL){ printf("File not open\n"); exit(2); } } while(1){ scanf("%d",&pos); /*番号の入力*/ if (pos==0) break; scanf("%s",tag.Name);/*名前*/ scanf("%d",&tag.Sex);/*性別*/ scanf("%d",&tag.Height);/*身長*/ scanf("%d",&tag.Weight);/*体重*/ fseek(Fp,sizeof(tag)*(pos),SEEK_SET); fwrite(&tag,sizeof(tag),1,Fp); memset(&tag,'\0',sizeof(tag)); } while(1){ scanf("%d",&pos); if (pos==0) break; fseek(Fp,sizeof(tag)*(pos),SEEK_SET); fread(&tag,sizeof(tag),1,Fp); printf("%s\n",tag.Name); printf("%d\n",&tag.Sex); printf("%d\n",&tag.Height); printf("%d\n",&tag.Weight); memset(&tag,'\0',sizeof(tag)); } Ret=fclose(Fp); if (Ret!=0){ exit(2); } }

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

  • ベストアンサー
  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.2

>うまくいかず 何がどのようにうまくいかないか、具体的に書いてください。 以下は、私がザッとソースをながめたときに気づいた点です。 1) main()の型はintです。 2) 入力時、何の入力を求めているかがわかりません。 printf()か何かを使ってプロンプトを出力する方がよいでしょう。 3) >float Weight;/*体重*/ >scanf("%d",&tag.Weight);/*体重*/ float型の変数に対する書式文字列が"%d"というのは、まずいです。 4) >printf("%d\n",&tag.Sex); >printf("%d\n",&tag.Height); >printf("%d\n",&tag.Weight); アドレスを出力したいのですか?

peitaro
質問者

お礼

回答ありがとうございます。 3)と4)が問題だったようです。

その他の回答 (1)

  • phoenix343
  • ベストアンサー率15% (296/1946)
回答No.1

ひんと。 ・C言語では配列の添え字はいくつから始まるんだっけ? ・fseekの戻り値を調べたら? 直したほうがよいと思われるもの ・C言語でintはサイズが決まっていない型なので、char、short、longのいずれかにすべきである。 ・tag.Nameは固定文字列のようだが入力のscanfでは、長さのチェックがされていないので危険

peitaro
質問者

お礼

回答ありがとうございます。 >C言語では配列の添え字はいくつから始まるんだっけ? ・0からですよね?どこに反映させれば??fseekの(pos)部分を(pos-1)の形に直せばいいのでしょうか? >fseekの戻り値を調べたら? ・戻り値はどちらも0だったので正常だとおもいます。 ・fwrite,freadについても1が返されました。 >C言語でintはサイズが決まっていない型なので、char、short、longのいずれかにすべきである。 ・問題がintで指定されています>< >tag.Nameは固定文字列のようだが入力のscanfでは、長さのチェックがされていないので危険 ・長さのチェックなどのエラー処理は、省かせていただきました。

peitaro
質問者

補足

実行結果としては↓のように表示されます。 1 TaroYamada 0 150 50 0 1 TaroYamada 1244928 1244932 1244936 0

関連するQ&A

  • 構造体のファイル書き込み&読み出しに関して2

    C言語を勉強しているものです。指定した番号に構造体を書き込み、指定した番号をの構造体を出力するプログラムを作成したいのですが、表示結果画像のようになってしまいます。 デバックしても、どこが違うのかがわかりません。説明不足かとは思いますがご教授お願いします。 ↓↓ソースコード↓↓ #include<stdio.h> #include<stdlib.h> struct S_data{ char Name[10+1];/*名前*/ int Sex;/*性別*/ int Height;/*身長*/ float Weight;/*体重*/ }; void FR_data(FILE *Fp,int pos); void FW_data(FILE *Fp,int pos); void OUP_data(struct S_data tag); void INP_data(struct S_data *tag); int RF_data(FILE *Fp,struct S_data *tag,int pos); int WF_data(FILE *Fp,struct S_data *tag,int pos); void main(){ FILE *Fp; int pos=0; int Ret; Fp=fopen("aaa.dat","r+b"); if(Fp==NULL){ Fp=fopen("aaa.dat","w+b"); if(Fp==NULL){ printf("File not open\n"); exit(2); } } while(1){ printf("入力の番号[0:終了]->"); scanf("%d",&pos); if(pos==0) break; FW_data(Fp,pos); } while(1){ printf("出力の番号[0:終了]->"); scanf("%d",&pos); if(pos==0) break; FR_data(Fp,pos); } Ret=fclose(Fp); } void FR_data(FILE *Fp,int pos){ struct S_data Temp; /*出力情報*/ int Ret; /*返却値*/ memset(&Temp,'\0',sizeof(Temp)); Ret=RF_data(Fp,&Temp,pos); /*情報の読み込み*/ if (Ret!=1){ printf("File not read\n"); }else{ OUP_data(Temp); /*情報の表示*/ } } void FW_data(FILE *Fp,int pos){ struct S_data wk; /*入力情報*/ int Ret; /*返却値*/ memset(&wk,'\0',sizeof(wk)); INP_data(&wk); /*情報の入力*/ Ret=WF_data(Fp,&wk,pos); /*情報の書き込み*/ if (Ret!=1){ printf("File not write\n"); } } void OUP_data(struct S_data tag){ printf("Name:%s\n",tag.Name); if (tag.Sex==0){ printf("Sex:M\n"); }else{ printf("Sex:F\n"); } printf("Height:%d\n",tag.Height); printf("Weight:%.2f\n",tag.Weight); } void INP_data(struct S_data *tag){ memset(tag,'\0',sizeof(tag)); printf("Name-->"); scanf("%s",&tag->Name); printf("Sex[0:M1:F]-->"); scanf("%d",&tag->Sex); printf("Height-->"); scanf("%d",&tag->Height); printf("Weight-->"); scanf("%f",&tag->Weight); } int RF_data(FILE *Fp,struct S_data *tag,int pos){ int Ret_I; /*fseek返却値*/ size_t Ret_S; /*fread返却値*/ Ret_I=fseek(Fp,sizeof(tag)*(pos),SEEK_SET); Ret_S=fread(tag,sizeof(tag),1,Fp); return Ret_S; } int WF_data(FILE *Fp,struct S_data *tag,int pos){ int Ret_I; /*fseek返却値*/ size_t Ret_S; /*fwrite返却値*/ Ret_I=fseek(Fp,sizeof(tag)*(pos),SEEK_SET); Ret_S=fwrite(tag,sizeof(tag),1,Fp); return Ret_S; }

  • C言語についてです。(困っております)

    プログラミング初心者で右も左もわからないので力になってください。 ニコニコ動画で、【第05回】ミクと学ぶC言語【if文】という動画を見ています。 その中で出てきたソースコードで、コンパイルまではうまくいくのですが コマンドプロンプトの画面で、文字を入力すると、動作を停止しました。 という通知が出てきます。 うまくできなくて困っているのでどうかわかりやすくアドバイスの程 よろしくお願いします。 ソースコードです。 ↓ /* BMI.c */ #include<stdio.h> int main(void){ double height,weight,BMI; printf("身長[ m]:"); scanf("%if",&height); printf("体重[kg]:"); scanf("%if",&weight); BMI=weight/height/height; printf("BMIは%fです。\n",BMI); if(BMI>=25){ printf("肥満です!\n"); }else if(BMI<18.5){ printf("低体重です!\n"); }else{ printf("標準です!\n"); } return 0;

  • C言語 構造体とvectorについてです

    C言語についてこんなプログラムをつくろうとしています。内容はこんなです↓↓ 1「番号・身長・体重を入力」←番号を入力するとこで0と入力するまでループ 2「今まで入力した値の平均を出力」←身長・体重それぞれの値の平均 3「番号を入力すると対応したデータ(1で打ち込んだデータ)を出力」 4「1を入力すると出力した値の修正をする」 3と4のループをして3のところで0を入力したら終了。。。 という感じです。 わからないとこは、最初のnumberの入力でデバックエラーがおきてしまうとこ(scanf("%d",&vec[i].number);の部分がおかしい?)、2は全体的にわかりません、3と4はなんとなくわかります。 構造体とvectorを使うのがわかりやすいと思って作成中ですが完全に止まってしまいました。 できれば1と2のプログラムを作成していただけませんか?よろしくおねがいします。 int main() { float height, weight; int i, b, D, P, J, M, E, number; vector<student_list> vec; student_list num; vec.push_back(num); for(i = 0;;i++) { printf("%d人目のデータです\n番号を入力して下さい\n", i + 1); scanf("%d",&vec[i].number); if(vec[i].number == 0) { return 0; } else { printf("身長と体重を入力して下さい\n"); scanf("%f\n%f",&vec[i].height,&vec[i].weight); printf("あなたのBMIは%.1fです\n",vec[i].weight*vec[i].weight/vec[i].height); printf("電子回路の点数を入力して下さい\n"); scanf("%d",&vec[i].D); printf("プログラミングの点数を入力して下さい\n"); scanf("%d",&vec[i].P); printf("国語の点数を入力して下さい\n"); scanf("%d",&vec[i].J); printf("数学の点数を入力して下さい\n"); scanf("%d",&vec[i].M); printf("英語の点数を入力して下さい\n"); scanf("%d",&vec[i].E); printf("国数英の平均点は%dです\n",(vec[i].J+vec[i].M+vec[i].E)/3); printf("5教科の平均点は%dです\n",(vec[i].D+vec[i].P+vec[i].J+vec[i].M+vec[i].E)/5); } } }

  • C言語の構造体について

    ご質問があります。 現在C言語について学習しているのですが、構造体を勉強しているときに下記のようなコードを作ったのですが storage size of 'mydata' isn't known というエラーが出てきてしまいます。 どこが間違っているのかがわかりません。 ご指南ご指導して頂けると助かります。 以下コード int main(void){ struct data mydata; mydata.name = "Yamada"; mydata.age = 30; mydata.height=173; mydata.weight = 65.4; printf("name = %s\n",mydata.name); printf("age = %d\n",mydata.age); printf("height = %d\n",mydata.height); printf("weight = %1f\n",mydata.weight); return EXIT_SUCCESS; }

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

  • C言語での構造体

    C言語の構造体で配列を扱うとき、 struct ○○{  char ○○[○] とすれば出来ますが、同じようにして構造体で二次元配列を扱うことは出来ますか? 一度組んでみたのですが、 #include<stdio.h> struct aaa{ int no; char name[128]; char y_name[128]; char n_name[128]; char s_name[128][128]; }; int main(void){ int i; struct aaa iryo[99]; printf("入力前\n"); /* 構造体配列に scanf()でデータを入力 */ for(i = 0; i < 3; i++) { // printf("input...\n"); scanf("%d", &iryo[i].no); scanf("%s", iryo[i].name); scanf("%s", iryo[i].y_name); scanf("%s", iryo[i].n_name); scanf("%s", iryo[i].s_name); } printf("入力後\n"); printf("出力前\n"); /* 入力データの確認 */ for(i = 0; i < 3; i++) { printf("番号:%02d 内容:%s Y分岐:%s N分岐:%s 他分岐:%s\n", iryo[i].no, iryo[i].name, iryo[i].y_name, iryo[i].n_name, iryo[i].s_name); } printf("出力後\n"); printf("%d",sizeof(struct aaa)); return 0; } としたら、エラーは出ませんが、実行すると何も表示されませんでした。

  • C言語についてです。

    EXELEファイルから値を読みこんで、各自のBMIと全体の身長・体重の平均値を求めるプログラムを作成したいんですが…C言語で…。途中までで混乱してしまい、あっているかも分からないのでお願いしたいです。よろしくお願いします。ヒントだけでもありがたいです。 下がそのファイルです。 height weight 170.7 52.9 166.8 71.3 171.4 58.5 173.4 76.7 176.1 80.2 184 89.1 179 64.7 177.2 78.5 177.7 80.7 173.8 64 167.7 60.3 181.6 72.3 162.4 53 177.4 69.6 178 76.4 174 77.2 185.4 86 172 68.5 172.7 60 166.5 62 171.3 69.6 177 79 174.8 82.6 167.5 69.2 176.8 80.1 181.5 76 177.3 76.4 169.4 51.8 165.2 73.2 175.3 72.3 181.5 72.4 171.5 68.8 176 73.2 186 99.8 167.3 65.5 176.1 78 183.3 77.2 177.5 59.5 180.3 62 171.2 74.7 175 87.2 176 80 171.8 50.6 平均身長の値を出すプログラムは出ているので…これもあわせてBMIと平均体重出してくれるとうれしいです。 /* basic claculation */ #include <stdio.h> #include <math.h> int main(void) { int i, ii; int ntotal; double sum_height; double weight[50], height[50]; double mean_height; char w[6],h[6]; FILE *fp; /* initial setting */ /* ntotal: total word number */ /* sum : total character number */ ntotal = 0; sum_height = 0; /* file open */ /* my data file is weight-height.data */ /* which is in my root directory */ fp = fopen("./weight-height.data","r"); /* skip character reading. */ fscanf(fp,"%s,%s",w,h); /* ntotal: total number */ /* sum : total value */ for (i=0;i<=47;i++) { if (feof(fp)) break; fscanf(fp,"%lf,%lf",&weight[i],&height[i]); printf(" weight = %lf height = %lf \n",weight[i],height[i]); sum_height = sum_height + height[i]; } fclose(fp); ntotal = i; printf(" 全人数 = %d \n",ntotal); mean_height = sum_height /ntotal; printf(", 平均身長 = %lf \n",mean_height); return(0); }

  • c言語 構造体

    大学での内容なのですが,『名前,数学の点数,英語の点数,国語の点数を格納できる(メンバに持つ)構造体を宣言し,この構造体の配列を用いて,3人分の情報をキーボードから入力後,各科目の平均点を画面に表示するプログラムを作成せよ.』という問題で,自分なりに作ってみたのですがうまくいきません.どなたか教えていただけませんか? 一応自分で作ったものを下に載せておきます. ================================================================ #include <stdio.h> #include <string.h> struct test { char name[20]; int sugaku; int eigo; int kokugo; }; int main(void) { struct test suzuki; int (suzuki.sugaku), (suzuki.eigo), (suzuki.kokugo); strcpy(suzuki.name, "Suzuki"); printf("氏名:鈴木 一馬\n"); printf("数学:"); scanf("%d", &suzuki.sugaku); printf("英語:"); scanf("%d", &suzuki.eigo); printf("国語:"); scanf("%d", &suzuki.kokugo); struct test tanaka; int tanaka.sugaku, tanaka.eigo, tanaka.kokugo; strcpy(tanaka.name, "Tanaka"); printf("氏名:田中 二郎\n"); printf("数学:"); scanf("%d", &tanaka.sugaku); printf("英語:"); scanf("%d", &tanaka.eigo); printf("国語:"); scanf("%d", &tanaka.kokugo); struct test yamamoto; int yamamoto.sugaku, yamamoto.eigo, yamamoto.kokugo; strcpy(yamamoto.name, "Yamamoto"); printf("氏名:山本 三弘\n"); printf("数学:"); scanf("%d", &yamamoto.sugaku); printf("英語:"); scanf("%d", &yamamoto.eigo); printf("国語:"); scanf("%d", &yamamoto.kokugo); printf("数学の平均点は%dです。\n", ((suzuki.sugaku + tanaka.sugaku + yamamoto.sugaku) / 3.0)); printf("英語の平均点は%dです。\n", ((suzuki.eigo + tanaka.eigo + yamamoto.eigo) / 3.0)); printf("国語の平均点は%dです。\n", ((suzuki.kokugo, + tanaka.kokugo + yamamoto.kokugo) / 3.0)); return (0); } ================================================================

  • C言語のqsortについて

    現在、qsortのコードに取り組んでいます。 if (strcmp(ad, "ASC") == 0) { qsort(sin, sizeof(cnt), sizeof(sin[0]), cmp_u); } else { qsort(sin, sizeof(cnt), sizeof(sin[0]), cmp_d); } 恐らくこちらのqsortでの第二引数が書き方を間違えていると思うのですが、修正の方法が分からず、どなたか教えて頂けないでしょうか? #include <stdio.h> #include <time.h> #include <string.h> #include <stdlib.h> static char ad[10]; int cmp_u(const void* a, const void* d) { return strcmp((char*)a, (char*)d); } int cmp_d(const void* a, const void* d) { return strcmp((char*)d, (char*)a); } int main() { int num1, num2; char op; float answer; int r,i; FILE* fp; char c[11]; char sin[1000][1000]; char ad[8]; fp = fopen("log.txt", "a+"); if (fp == NULL) { printf("ファイルオープン失敗\n"); return -1; } while (1) { r = scanf("%d%c%d", &num1, &op, &num2); if (r != 3) { puts("input error"); return 1; } if (op == '+') { answer = num1 + num2; } else if (op == '-') { answer = num1 - num2; } else if (op == '*') { answer = num1 * num2; } else if (op == '/') { answer = (float)num1 / num2; } time_t t = time(NULL); struct tm* tm = localtime(&t); printf("%d/%02d/%02d ", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday); printf("%02d:%02d:%02d ", tm->tm_hour, tm->tm_min, tm->tm_sec); printf("%d%c%d,%f\n", num1, op, num2, answer); fprintf(fp, "%d/%02d/%02d ", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday); fprintf(fp, "%02d:%02d:%02d ", tm->tm_hour, tm->tm_min, tm->tm_sec); fprintf(fp, "%d%c%d,%f\n", num1, op, num2, answer); printf("計算を続けますか?"); scanf("%s\n", &c); if (strcmp(c, "no") == 0) { break ; } } fclose(fp); fp = fopen("log.txt", "r"); int cnt = 0; for (i = 0;i < 1000;i = i + 1) { if (fgets(sin[i], sizeof(sin[0]), fp)) ++cnt; else break; } fclose(fp); printf("ASC or DESC: "); scanf("%s", ad); if (strcmp(ad, "ASC") == 0) { qsort(sin, sizeof(cnt), sizeof(sin[0]), cmp_u); } else { qsort(sin, sizeof(cnt), sizeof(sin[0]), cmp_d); } for (i = 0;i < cnt;i = i + 1) { printf("%s", sin[i]); } return 0; }

  • C言語のプログラム組んだのですが完成させてください

    C言語のプログラムを断片的に作成したのでつなげて完成させて頂けないでしょうか? このサイトでコンパイルなど出来ます http://ideone.com/ 以下の問題を解きました また問題文の指示には必ずしたがってください。また、この文章の条件でなく、人数が4人とかそれ以外の時でも出来るようなプログラムでお願いします。 http://i.imgur.com/nuzJv2v.png http://i.imgur.com/c7f3Vh2.png http://i.imgur.com/5aCqDO0.png http://i.imgur.com/9u8hHIM.png 問題は画像になっています #include<stdio.h> #include<string.h> /*構造体型struct Dataの宣言*/ struct Data{ char name[20]; int height; double weight; } data[100]; int cnt; int main(void) { int a; do { printf("**************身長・体重の表示***************\n\n"); printf(" データファイルの読み込み・・・・・(1)\n"); printf(" 全てのデータを表示・・・・・・・・(2)\n"); printf(" 特定のデータを表示・・・・・・・・(3)\n"); printf(" 終わり・・・・・・・・・・・・・・(4)\n\n"); printf("処理番号を入力してください\n"); scanf("%d",&a); } while(a<1 || a>4); return a; } /*read_file関数の宣言*/ int read_file(void) { FILE *fp; char filename[20]; cnt=0; printf("読み込むファイルの名前を入力してください。\n"); scanf("%s",filename); fp=fopen(filename,"r"); if(fp==NULL){ printf("ファイルをオープンできませんでした。\n"); return 1; } while(fscanf(fp,"%c %d %lf",data[cnt].name,data[cnt].height,data[cnt].weight)!=EOF){ cnt++; fclose(fp); printf("ファイルを読み込みました。\n"); } return 0; } /*p_all関数の宣言*/ int p_all(void) { int i; printf("名前 身長(cm) 体重(kg)\n"); for(i=0;i<cnt;i++) { printf("%-2s %5d %.2f\n",data[i].name,data[i].height,data[i].weight); } } 最初の処理番号を入力した所で終わってしまいます、何とか改変してくださいお願いします 補足

専門家に質問してみよう