C言語のファイル入出力で困っています

このQ&Aのポイント
  • C言語のファイル入出力に関して困っています。プログラムがコンパイルはできるものの、実行がされない状態です。具体的なプログラムの内容や問題点を説明しました。
  • プログラムでは、sprintfを使ってファイルを作成し、fprintfで読み込み、countを用いて繰り返し別のファイルを読み込み・作成しています。しかし、何度見直してもエラーの原因がわからず、困っています。
  • プログラムの実行結果を見る限りでは、fscanfの部分に問題があるようです。具体的なエラーメッセージや想定しているファイルの形式についても説明しました。ご助力をお願いします。
回答を見る
  • ベストアンサー

ファイルの入出力で困っています(C言語)

はじめまして、nathan3と申します。 昔、さらっとC言語を学んでいたので、仕事場でも活用できればと思い、勉強しなおしています。 以下のプログラムですが、コンパイルはするものの、実行がなされません。 sprintfをつかってファイルを作り、fprintfで読み込み、countで繰り返し別名のファイルを読み込み・作成し…といったプログラムを書いているつもりです。 調べながら書いた稚拙なプログラムですが、ここがちがう!というところをお教えいただけると大変助かります。 #include <stdio.h> int main(void){ FILE *fp,*fo; char *fname1; char *fname2; char s[100],t[100]; int ret,count; for(count = 0 ; count < 3 ; count++) { sprintf(fname1, "sankasha%d.txt", count); fp = fopen(fname1, "r"); if (fp == NULL){ printf("%s can't open a file\n", fname1); return -1; } sprintf(fname2, "matome%d.txt", count); fo = fopen(fname2,"w"); if (fo == NULL){ printf("%s can't open a file\n", fname2); return -1; } printf("--fscanf---"); while( (ret = fscanf(fp,"%[^,],%s", s, t)) != EOF ){ fprintf(fo,"%s ", t); } } fclose(fo); fclose(fp); return 0; } 何度見直しても間違いが見つからず困窮しております。 どうぞ、みなさまのお力をお貸しください! よろしくお願いいたします。

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

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

char *fname1; ... sprintf(fname1, "sankasha%d.txt", count); fname1はポインターであって、配列ではないですよね。 そこにsprintfしてもアクセス違反などで強制終了でしょう。 char fname1[100]; のように配列をちゃんと確保するか、 glibcやBSD系のlibcが使えるならsprintfではなくasprintfを使うかでしょうね。 asprintf(&fname1, "sankasha%d.txt", count); fp = fopen(fname1, "r"); if (fp == NULL){ printf("%s can't open a file\n", fname1); return -1; } free(fname1); あと、バッファが溢れないという自信がよほど無い限りはsprintfは使わないですね。 ISO C99で標準化されたsnprintfを使うのが普通だと思います。 まあ、何かのデータの整理をするプログラムはよほど速度が問題にならない限り、自分だったらPython、Perl、Rubyなどのスクリプト言語でプログラムを書くと思いますが。

nathan3
質問者

お礼

>glibcやBSD系のlibcが使えるならsprintfではなくasprintfを使うかでしょうね。 プログラムはさまざまな書き方があって面白い反面難しいです。 hanabutakoさんから提案いただいたものは正直まだよくわかっていませんが、いずれ使えるよう精進したいと思います。 詳細にご説明いただき、ありがとうございました。

その他の回答 (2)

  • maiko0318
  • ベストアンサー率21% (1483/6970)
回答No.3

とりあえず、 char fname1[20]; char fname2[20]; にしましょう。 char *fname1; char *fname2; ですと、ポインターが作られるだけで文字列の格納エリアは作られません。

nathan3
質問者

お礼

無事、実行できました。 ありがとうございます。 ポインタの使い方がいまいち理解できていませんでした。 再度、ポインタの使い方を確認し勉強しなおしたいと思います。

  • Tasuke22
  • ベストアンサー率33% (1799/5383)
回答No.1

本当にコンパイルエラー出ないのかな? 出ると思うんだけど。 ワーニングでも潰す必要あり、ですよ。 また実行出来たとしたらエラーメッセージが出ると思うのですが、 エラーメッセージを無視して先には進めません。 質問する場合、これらは全てアップしないと回答も付きにくいでしょう。 さてコードですが突っ込みどころが多過ぎます。 取り敢えず1点、fopenが成功する前にsprintfの実行は不可能でしょう。

nathan3
質問者

お礼

ご指摘ありがとうございます。 おっしゃるように、質問が漠然としておりました。 >取り敢えず1点、fopenが成功する前にsprintfの実行は不可能でしょう。 sprintfは指定した形式の文字列として格納するという認識で、独立して実行はできると思っていたのですが、fopenしないとsprintfが実行できないというのは書き方の問題でしょうか。

関連するQ&A

  • c言語プログラムについて

    http://www.post.japanpost.jp/zipcode/dl/kokagi.html から全国一括(1,735,160Byte)をダウンロード このファイルを使って、 Linuxマシン上で、 例えば、北海道札幌市中央区旭ケ丘 と入力すれば、0640941 と返却されるプログラム(引数はコマンドラインで)をcで作成したいと思っているのですが、ファイルのダウンロードとファイルの読み込みまでは出来たのですが、その後の「北海道札幌市中央区旭ケ丘 と入力すれば、0640941」からが分かりません。どなたか続きを教えて頂けないでしょうか? 使用OS:fedora 一応、ソースを載せておきます #include <stdio.h> int main(void){ FILE *fp; char *fname="ken_all.csv"; char d[100]; char e[100]; char f[100]; char g[100]; char h[100]; char i[100]; int ret,a,b,c; fp = fopen("ken_all.csv", "r"); if (fp == NULL) { printf("ファイルをオープンできませんでした\n",fname); return -1; } while( (ret = fscanf( fp, "%[^, ],%d,%d,%s,%s,%s,%s,%s,%s", &a, &b, &c, d, e, f, g, h, i ) ) != EOF ){ printf( "%d %d %d %s %s %s %s %s %s", a, b, c, d, e, f, g , h , i); } fclose(fp); return 0; }

  • C言語 ファイル操作

    現在書籍にてC言語を用いたファイル操作を勉強しています。 何故か動作が停止してしまい次に進めません、よろしくお願いします。 #include <stdio.h> #pragma warning(disable:4996) int main(void) { FILE *fp; char fname[64]; printf("ファイル名:"); scanf_s("%s", fname); //ポインタfpが指すストリーム fp = fopen(fname, "r"); if (fp == NULL) printf("\aファイルをオープンできません\n"); else fclose(fp); return(0); } エラーメッセージ ハンドルされない例外が 0xFEFEFEFE (helloworld.exe) で発生しました: 0xC00001A5: 無効な例外ハンドラー ルーチンが検出されました。 (パラメーター: 0x00000003)。

  • CSVファイルの入出力と計算

    C言語の質問です。 勉強不足で聞くのは申し訳ないのですが、 自分であれこれとやってみて、どうしていいのか分からなくなってしまいました。 csvファイルの中身は、6行目までは不要な文字列などが入っていて、7行目から使いたい数値となっています。その数値は5桁と分かっています。 さらに、データ数としては、約300000行~10000000行とデカイ上に定まっていません。 その数値に値をかけて変換してファイルとしてだしたいのですが、どうすればよいのでしょうか? 下のようなイメージ↓(値はテキトー) *********************************** 元ファイル→掛ける値→後ファイル 54321→→ *10/12365→ 1.4243 : : : : ************************************ 以下は自分で書いたものですが、 ????????????にしてあるあたり(ファイルを読み込む部分) がどうすればいいかわかりません。 変数が色々あるのは迷走の証です。 どうぞ、よろしくお願いします。 int main(){ FILE *in,*out; char fname1[30],fname2[30]; char s[5]; double n1; int n,i=0; int start=7; int line=0; printf("読み込むファイル名を入力してください\n"); scanf("%s",&fname1); in=fopen(fname1,"r"); out=fopen(fname2,"r"); if(in==NULL){ printf( "ファイルが開けません\n",fname1); return -1; } else{ ???????????????????? ?????????????????? printf("%d \n",n1); fprintf(out,"%s \n",n1); } } printf("書き込むファイル名を入力してください\n"); scanf("%s",&fname2); fclose(in); fclose(out); return 0; }

  • C言語 iMacでのファイル入出力

    #include <stdio.h> int main() { FILE *fp; fp=fopen("test.txt","w"); if (fp==NULL){ perror("ファイル・オープンに失敗しました\n"); return -1; }else printf("ファイルを正常に開きました\n"); fprintf(fp,"これが初めてのファイル入出力です\n"); if (fclose(fp)!=0){ perror("ファイル・クローズに失敗しました\n"); return -1; }else printf("ファイルを正常に閉じました\n"); return 0; } これを実行してもどこにもtest.txtというファイルがありません。 同じプログラムをwinでも実行してみたところ正常にファイルが作られました。 mac初心者なもんで、どうすればいいのでしょうか?

  • C言語でコマンドmvを実行

    name.txtというテキストファイルがあり、中身は 123 abc 456 def … となっています。 このテキストファイルを1行ずつ読み込んで、 mv 123/ abc/ のようにテキストファイルの中身に沿って、ディレクトリの名前を一気に変更したいのですが、上手くいきません。 どこがおかしいか、教えていただけないでしょうか。 /* header files */ #include <stdio.h> #include <stdlib.h> /* main */ int main(int argc, char *argv[]) { char *buff; float ret, ter; char a[50],b[50]; FILE *fp, *fq; fp = fopen(argv[1], "r"); while((ret = fscanf(fp,"%s %s",a,b)) != EOF){ sprintf(buff, "mv %s %s",a,b); system(buff); } fclose(fp); return EXIT_SUCCESS; }

  • ファイル入出力について教えて下さい。2

    ご覧いただきありがとうございます。 何度も低レベルな質問で申し訳ありません。 A.PRMというファイルに、 I have a pen. He has a pen. と2行の文章が入っています。 これを読み取り、printfで画面表示させたいのですが、 #include <stdio.h> int main(void) { FILE *fp; char a[50]; char b[50]; if( (fp=fopen("A.PRM", "r" )) != EOF ) { fgets( a, 49, fp ); fgets( b, 49, fp ); } fclose( fp ); printf( "a = %s\n", a ); printf( "b = %s\n", b ); return 0; } とすると、fgetsで余分な改行が入ってしまいます。 fgetsの代わりにfscanfを使用すると、今度はスペースの前までしか読み込んでくれず、「a = I」「b = He」と表示されてしまいます。 どうしたらよいでしょうか? 是非ご回答いただきたいです。よろしくお願いいたします。

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

    ファイルを読み込む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'を数えれるようにしてください。御指摘お願いします。

  • C言語の課題なのですが、助けてください

    C言語のプログラミングの課題で、「以下のプログラムをキーワードを引数として入力できるように変更する(argvを利用する)」という問題なのですが、プログラミングが苦手な私にはさっぱりわからず、大変困っています。設問のプログラミングがわかる方がいらっしゃいましたら、教えていただけると大変助かります。よろしくお願いします。 #include <stdio.h> #include <string.h> #include <stdlib.h> #define MAX_LEN 256 int main(int argc, char *argv[]) { FILE *rfp; FILE *wfp; int i, score; double evalue; char id[MAX_LEN], name[MAX_LEN], fname[MAX_LEN]; char keyword[] = "glu"; for(i = 0; i < 100; i++){ sprintf(fname,"files/%d.txt",i); if((rfp = fopen(fname, "r")) == NULL) { printf("入力ファイルが存在しません。\n"); return (EXIT_FAILURE); } while (fscanf(rfp,"%s\t%s\t%d\t%f", id, name, &score, &evalue) != EOF){ if (strstr(name,keyword) != NULL){ printf("%s\n",id); } } fclose(rfp); } return (EXIT_SUCCESS); }

  • C言語について

    以下のプログラムについてです test.txtというファイルから文字を読み込み、異なる単語の数を求めるプログラムです。 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<ctype.h> #define NMAX 80 #define LMAX 5000 void count(FILE*, int); void all_words(FILE *); FILE *fp, *fp2; char *fn="test.txt"; char *fn2="total word.txt"; int main(void){ int p=0, x, count, l,k, t=0; char name[LMAX][NMAX], word1[NMAX], word2[NMAX]; char *tp, *tp2; if((fp=fopen(fn,"r"))==NULL){ printf("Can't open '%s'.\n",fn); exit(1); } if((fp2=fopen(fn2,"w"))==NULL){ printf("Can't open '%s'.\n",fn2); exit(1); } for(count=0;count<LMAX;count++){ if(fgets(name[count],NMAX,fp)==NULL)break; p++; } for(count=0;count<p;count++){ for(x=0;x<NMAX;x++){ word1[x]=tolower(name[count][x]); } tp=word1; while((tp2=strtok(tp,"\n !?()*-;:.,_\"[]"))!=NULL){ if(*tp2=='\''){ if(*(tp2+1)=='`') t=1; tp2++; } strcpy(word2,tp2); k=l=strlen(word2)-1; if(word2[k]==('\'' & l)) word2[l]='\0'; if(word2[0] =='\'' &&t==0){ if(word2[1]!='\0'){ fputs(word2+1,fp2); fputc('\n',fp2); } } else{ if(word2[0]!='\0'){ fputs(word2,fp2); fputc('\n',fp2); } } tp=NULL; } } fclose(fp); fclose(fp2); all_words(fp2); return 0; } void all_words(FILE* fp2){ char word3[NMAX]; int n=0; if((fp2=fopen(fn2,"r"))==NULL){ printf("Can't open '%s'.\n", fn2); exit(1); } for(;;){ if(fgets(word3, NMAX,fp2)==NULL) break; n++; } fclose(fp2); count(fp2,n); } void count(FILE* fp2, int n){ int count, x, y=0; char *m=(char *)malloc(n*NMAX); char *xp,*yp; if((fp2=fopen(fn2,"r"))==NULL){ printf("Can't open '%s'.\n", fn2); exit(1); } for(count=0,xp=m; count<n;count++,xp+=NMAX){ fgets(xp,NMAX,fp2); } qsort(m,n,NMAX,(int (*)(const void*, const void*))strcmp); count=1; for(x=0,xp=m,yp=m+NMAX;x<n-1;xp+=NMAX,yp+=NMAX,x++){ if(strcmp(xp,yp)==0){ y++; count++; } else{ sprintf(xp+strlen(xp)-1," (%d)",count); count=1; } }    printf("KIDN OF WORD:%d\n",n-y); free(m); fclose(fp2); } このプログラムを実行するとメモリリークになってしまいます。 どうしたら良いでしょうか?

  • C言語について

    以下のプログラムについてです。 test.txtというファイルを読み込み、その中の異なる単語の数を求めるプログラムです。 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<ctype.h> #include<stddef.h> #define NMAX 80 #define LMAX 5000 void count(FILE*, int); void all_words(FILE *); FILE *fp, *fp2; char *fn="alice.txt"; char *fn2="total word.txt"; char *ignore="\n !?()*-;:.,_\"[]"; int main(void){ int p=0, x, count, l, t=0,k=0; char name[LMAX][NMAX], word1[NMAX], word2[NMAX]; char *tp, *tp2; if((fp=fopen(fn,"r"))==NULL){ printf("Can't open '%s'.\n",fn); exit(1); } if((fp2=fopen(fn2,"w"))==NULL){ printf("Can't open '%s'.\n",fn2); exit(1); } for(count=0;count<LMAX;count++){ if(fgets(name[count],NMAX,fp)==NULL)break; p++; } for(count=0;count<p;count++){ for(x=0;x<NMAX;x++){ word1[x]=tolower(name[count][x]); } tp=word1; while((tp2=strtok(tp,ignore))!=NULL){ if(*tp2=='\''){ if(*(tp2+1)=='`') t=1; tp2++; } strcpy(word2,tp2); k=l=strlen(word2)-1; if(word2[k]==('\'' & l)) word2[l]='\0'; if(word2[0] =='\'' &&t==0){ if(word2[1]!='\0'){ fputs(word2+1,fp2); fputc('\n',fp2); } } else{ if(word2[0]!='\0'){ fputs(word2,fp2); fputc('\n',fp2); } } tp=NULL; } } fclose(fp); fclose(fp2); all_words(fp2); return 0; } void all_words(FILE* fp2){ char word3[NMAX]; int n=0; if((fp2=fopen(fn2,"r"))==NULL){ printf("Can't open '%s'.\n", fn2); exit(1); } for(;;){ if(fgets(word3, NMAX,fp2)==NULL) break; n++; } fclose(fp2); count(fp2,n); } void count(FILE* fp2, int n){ int count, x, y=0; char *m=(char *)malloc(n*NMAX); char *xp,*yp; if(m==NULL){ return ; } if((fp2=fopen(fn2,"r"))==NULL){ printf("Can't open '%s'.\n", fn2); exit(1); } for(count=0,xp=m; count<n;count++,xp+=NMAX){ fgets(xp,NMAX,fp2); } qsort(m,n,NMAX,(int (*)(const void*, const void*))strcmp); count=1; for(x=0,xp=m,yp=m+NMAX;x<n-1;xp+=NMAX,yp+=NMAX,x++){ if(strcmp(xp,yp)==0){ y++; count++; } else{ count=1; } } printf("KIDN OF WORD:%d\n",n-y); if(m){ free(m); m=NULL; printf("%p\n",m); } fclose(fp2); } このプログラムを実行するとメモリリークになってしまいます どうしたら良いでしょうか?