• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:構造体とfscanf)

構造体とfscanfでファイルから文字列を読み込む方法

Wr5の回答

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

>1が必須の理由が分からないです。 >なぜなのでしょうか?(長さを指定しなくても動いたので) バッファオーバーランを実施することができるから…です。 現在は20バイト確保していますが、そこに200文字読み込ませることもできます。 未指定ですからね。 そして、あふれたデータがどこに書き込まれるのか? ということです。 # セキュリティホール関係で「バッファオーバーランにより任意のコードが実行できる云々」というのはそういうモノです。 まぁ、そういう意味ではNo.1での私の回答もバッファオーバーランできるのですが。

nanaka2223
質問者

補足

おやよく見たらお久しぶりです♪ 元気そうで何よりですね もうしばらくしたらクリスマスですよ おいしいご飯が楽しみです。 Wr5さんもクリスマスはたのしみますか? 世間話はここまでにして、バッファオーバーランをここで聞く事になるとはおもいませんでした なるほどです。 一定数の文字以上になったら禁止にしていたので気づきませんでした。 (練習用には書いてませんが) あふれたデータ云々はよくわからないようなことになりそうなら、プログラムとして問題ないなら放置。 バグがでてきたらその時処理するでしょうね。 ただ、こう書くとバグになるでしょうっと思っていたものが書いた後は正常に動く事もあって面白いですよね

関連するQ&A

  • ファイル読込時に構造体の文字列ポインタに割当てたいと

    ファイル読込時に構造体の文字列ポインタに割当てたいと思っています。 (new 演算子を使用します。) 文字列の長さが不定です。 どうすれば、文字列の長さを知ることができますか? 以下のようなところまでは作れましたが、 困っています。 void loaddata()のfscanf関数の部分です。 ほかにも関数の void outputdata() void deletedata() がありますが、長いので省略しました。 ********************************************************** #include<stdio.h> #include<string.h> class data { public: struct basic { char *name; int age; struct basic *next; }; private: struct basic *base; struct basic *base_top; int cnt; public: data::data() { cnt=0; } void inputdata(char *name,int age) { if(cnt==0) { base=new basic; base_top=base; base->age=age; int len=strlen(name); base->name=new char[len+1]; strcpy(base->name,name); cnt++; } else { base->next=new basic; base=base->next; base->age=age; int len=strlen(name); base->name=new char[len+1]; strcpy(base->name,name); cnt++; } } void savedata() { base=base_top; FILE *fp; fp=fopen("dat.txt","w"); for(int i=0;i<cnt;i++) { fprintf(fp,"%s\t%d\n",base->name,base->age); base=base->next; } fclose(fp); } void loaddata() { if(cnt!=0){deletedata();} cnt=0; FILE *fp; fp=fopen("dat.txt","r"); while(1) { fscanf(fp,"%s\t%d\n",base->name,base->age); } } };

  • fscanfを使った読み取り

    datファイルの内容が 100,KAWAI YOSIKI,299,AKASAKA NOBORU・・・・ のような感じになっていて その中身を構造体配列に格納したい場合についてお聞きしたいです。 構造体の型は struct date { int id; char name[80]; }; のような感じです。自分なりに考えてfscanfを使って(省略部分あり) struct o_kaiin[20]; fp=fopen("date.dat","rb"); for(i=0;i<20;i++) { fscanf(fp,"%d%s",&o_kaiin[i].id,&o_kaiin[i].name); } という感じで格納しようとしたのですが、エラーが起こってしまいます。 名前の間に空白が無ければ問題ないのですが、このような文字列の場合 どのようにして読み込めばいいのでしょうか?ご教授ください。

  • fscanfで格納された変数がおかしいです。

    fscanfで格納された変数がおかしいです。 ダブルポインタで定義した変数にfscanfでファイルから文字列データを読み込んでいるのですが 表示がおかしな事になっています。 読み込んだファイルの内容は、 aiueo kakikueko sasisuseso tatituteto です。 表示された結果が kakikueko sasisuseso tatituteto kakisasitatituteto sasitatituteto tatituteto 自分では解決しずらいのでここで質問をさせて頂くことになりました。 C/C++で記述してあるのですが、以下にソースを載せておきますのでご指摘ください。 /* double pointa */ #include <stdio.h> #include <stdlib.h> #define MAXSIZE 256 char** size; // TEST void test(void) { for(int l = 0; l < 3; l++) { printf("\n%s", &size[l]); } } int main() { FILE* fp; int c = -1; char moji[MAXSIZE]; if((fp = fopen("test.txt","rb")) == NULL) { printf("error"); exit(1); } while(fscanf(fp,"%s",moji) != EOF) c++; size = (char**)malloc(sizeof(char) * MAXSIZE * c); // 初めに戻す fseek(fp, 0, SEEK_SET); // 最初の文だけ取り出す fscanf(fp,"%s",moji); // 一文を格納する for(int l = 0; fscanf(fp, "%s", &size[l]) != EOF; l++) { printf("\n%s", &size[l]); } printf("\n"); test(); fclose(fp); getchar(); free(size); return 0; } test関数内で表示するとおかしな結果がでるのですが何故かわかりません。 よろしくお願いします。

  • fscanf関数について

    -------------------------------------------------- #include<stdio.h> #include<stdlib.h> int main() { FILE*fp; int ch,dt; char ss[80]; if((fp=fopen("bbb.txt","w"))==NULL){ printf("出力ファイルをオープンできません.\n"); exit(1); } fprintf(fp,"%c",'A'); fprintf(fp,"%s\n","abcdeABCDE"); fprintf(fp,"%d\n",1234); fclose(fp); if((fp=fopen("bbb.txt","r"))==NULL){ printf("入力ファイルをオープンできません.\n"); exit(1); } ch=fgetc(fp); printf("ch=%c\n",ch); fscanf(fp,"%s",ss); printf("ss=%s\n",ss); fscanf(fp,"%d",&dt); printf("dt=%d\n",dt); fclose(fp); return 0; } -------------------------------------------------- 以上のプログラムで、プログラムの通り「bbb.txt」は、 AabcdeABCDE 1234 となっております。 そこで疑問なのですが、「ch=fgetc(fp);」は1文字読み込みなので、'A'だけと分かるのですが、「fscanf(fp,"%s",ss);」はfpからの読み込みで何故、 AabcdeABCDE 1234 の全部を読み込まず、'A'を抜かした、「abcdeABCDE」だけを読み込んでくれるのか? 後、「fscanf(fp,"%d",&dt);」は何故「AabcdeABCDE」を抜かした、「1234」だけを読み込んでくれるのかが分かりません。 「fscanf(fp,"%d",&dt);」については数値だけを読み込んでくれるのかと思い、 ch=fgetc(fp); printf("ch=%c\n",ch); fscanf(fp,"%s",ss); printf("ss=%s\n",ss); の部分を無くせば、「1234」だけを読み込んでくれるのかと思ったのですが、数値は正しく表示されません。 以上教えていただければ嬉しいです。

  • fscanfの使い方

     現在C言語の勉強をしているのですが、ファイル入力のfscanfの使い方がいまいちわかりません。  テキストファイル「TEST4K01.txt」には 「A01MATSUMOTO 090075100」が入ってるのですが、それぞれ構造体に直接振り分けて格納したい為fscan関数を使って下のソースを書いたのですがコンパイルするといつも以上終了してしまいます。大変申し訳ないのですが、誰か助言を御願いします。 #include<stdio.h> #include<stdlib.h> struct score { char clas_i; char num_i; char name[10]; int eigo_i; int sugaku_i; int kokugo_i; }; FILE *ifp; int main(void) { struct score dt; if((ifp = fopen("TEST4K01.txt", "r")) == NULL){ printf("ファイルエラー\n"); exit(1); } fscanf(ifp, "%1c%2d%10c%3d%3d%3d\n", &dt.clas_i, &dt.num_i, &dt.name, &dt.eigo_i, &dt.sugaku_i, &dt.kokugo_i); printf("%s", dt.clas_i); printf("%d", dt.num_i); printf("%s", dt.name); printf("%d", dt.eigo_i); printf("%d", dt.sugaku_i); printf("%d", dt.kokugo_i); fclose(ifp); return 0; }

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

  • 構造体の配列について

    --------------------------------------------------- #include<stdio.h> #include<string.h> struct person{ char name[80]; int height; int weight; }; int main() { struct person dt[10]; strcpy(dt[1].name,"日本太郎");    //// (1) //// dt[1].weight=70; dt[1].height=180; dt[5]=dt[1];    //// (2) //// printf("%s %d %d \n",dt[1].name,dt[1].weight,dt[1].height); return 0; } ----------------------------------------------------- 以上のプログラムは参考書に記述されていたものですが、(1)の部分で、配列名dtに「"日本太郎"」を設定するならわかるのですが、配列の1つの要素「dt[1]」に「"日本太郎"」を設定しているというように見え、これはエラーが出ると感じたのですが出ません。 char dt[10]; strcpy(dt[1],"日本太郎"); 以上のようにしてしまっているというイメージがあります。 後、(2)の部分もよくイメージがわきません。 以上、どのような仕組みになっているのか教えていただければ嬉しいです。

  • fscanf()

    fcanf()がうまくいきません。 画面には、42640888のような数値が表示されます。 どこが間違ってるか教えてください。 (test.txtに23と書いてあるとします。) #include<stdio.h> int main(void) {    FILE *fp;    FILE *fp1;    char str[10];    int a;    fp=fopen("test.txt","r")    fp1=fopen("a.txt","w")    while(!feof(fp)){       fgets(str,8,fp);       fputs(str,fp1);    }    fscanf(fp,"%d",&a);    printf("%d",a);   fclose(fp);   fclose(fp1);   return 0; }

  • 構造体内のポインタのポインタについて

    ポインタを理解するために以下のようなテストプログラムを作りました。 test.h --- typedef struct i_info{ int i_id; char i_name[64]; } I_INFO; typedef struct j_info{ int j_id; char j_name[64]; } J_INFO; typedef struct k_info{ int k_id; char k_name[64]; } K_INFO; typedef struct info{ int id; char name[64]; I_INFO iinfo; J_INFO *jinfo; K_INFO **kinfo; } INFO; --- test.c --- 1 #include <stdlib.h> 2 #include <stdio.h> 3 #include "./test.h" 4 5 int main(int argc, char **argv) 6 { 7 INFO info; 8 J_INFO j; 9 K_INFO k; 10 K_INFO *pk=NULL; 11 12 memset (&info,NULL,sizeof(info)); 13 memset (&j,NULL,sizeof(j)); 14 memset (&k,NULL,sizeof(k)); 15 16 info.id = 1; 17 memcpy(info.name,"***",3); 18 19 info.iinfo.i_id = 2; 20 memcpy(info.iinfo.i_name,"*i*",3); 21 22 info.jinfo = &j; 23 j.j_id = 3; 24 memcpy(j.j_name,"*j*",3); 25 26 info.kinfo = &pk; 27 pk= &k; 28 k.k_id = 4; 29 memcpy(k.k_name,"*k*",3); 30 31 printf( "%d\n",info.id); 32 printf( "%s\n",info.name); 33 printf( "%d\n",info.iinfo.i_id); 34 printf( "%s\n",info.iinfo.i_name); 35 printf( "%d\n",info.jinfo->j_id); 36 printf( "%s\n",info.jinfo->j_name); 37 /* 38 printf( "%d\n",info.kinfo->k_id); 39 printf( "%s\n",info.kinfo->k_name); 40 */ 41 } --- 38,39行目をコメントアウトするとコンパイルは通るのですが、 そのままだとコンパイルエラーになります。 なぜいけないのでしょうか?理由を教えてください。

  • 構造体の型について

    ある構造体をxxxと名づける以下のプログラムを作成しました。 ーーーーーーーーーーー #include <stdio.h> #include <string.h> main() { typedef struct { char variable[64]; char type[64]; char value[512]; } xxx; xxx aaa; strcpy(aaa.variable,"bbb"); printf("%s\n",aaa.variable); } ーーーーーーーーーーー これは動き、bbbと表示されます。 しかしながら、構造体のポインタを使用した 以下のプログラムではコンパイルはとおりますが実行時にコアダンプして落ち ます。 ーーーーーーーーーーーーーーーーーーーー #include <stdio.h> #include <string.h> main() { typedef struct { char variable[64]; char type[64]; char value[512]; } xxx; xxx* aaa; strcpy(aaa->variable,"bbb"); printf("%s\n",aaa->variable); } ーーーーーーーーーーーーーーーーーーーーーーー 両プログラムの意図はまったく同じなのに何故いけないのでしょうか。