• 締切済み

ファイルの入出力に関する質問

ファイルに書かれたテキストから一部分だけを抜き出し、 それを再び別のファイルに書き込むプログラムを作成したいのですが、 書き込んだファイルの中身が何もないという事態に陥りました。 プログラムは以下の通りです。 #include <stdio.h> #include <stdlib.h> #define STR_MAX 256 /* 文字列入力用配列長 */ int main(void) { FILE *fp, *fo; /* ファイルポインタ用 */ char buff[STR_MAX]; /* 文字列用 */ char ch1;/* 文字入力前 */ char ch2; /* 文字入力後 */ if((fp = fopen("in.txt", "r")) == NULL){ /* 入力ファイルオープン */ printf("入力ファイルがオープンできません\n"); exit(1); /* 強制終了 */ } if((fo = fopen("out.txt", "w")) == NULL){ /* 出力ファイルオープン */ printf("出力ファイルがオープンできません\n"); exit(1); /* 強制終了 */ } while(1){ /* 永久ループ */ ch1=ch2; ch2 = fgetc(fp); /* ファイルfpから1文字読み込み */ if(ch2 == EOF){ /* 読み込み終了 */ break; /* ループ脱出 */ } if(ch1=="目"&&ch2=="的"){ /*目的の項目だけ書き込む*/ while(ch1!="方"||ch2!="法"){/*方法がきたら書き込み停止*/ ch1=ch2; ch2 = fgetc(fp); fprintf(fo, "%c",ch2); }} } fclose(fp); /* 入力ファイルクローズ */ fclose(fo); /* 出力ファイルクローズ */ return(0); } ちなみに抜き出す前のファイルは 「背景:近年、日本経済において・・・<中略>・・・目的:本研究では・・・・・・方法:本研究では・・・・・背景:最近、アメリカ市場における・・・目的:今年度における・・・方法:・・・」 のように改行されずに入力されており、 そこから、目的の事項だけを取り出し 「目的:本研究では・・・<中略>・・・。目的:今年度における・・・」 のようなファイルを作りたいと思っています。 どうかご教授ください。

みんなの回答

回答No.6

とりあえず、「目的:」と「方法:」をstrncmp関数で文字列比較するやり方を参考まで。。 #include <stdio.h> #include <string.h> /* strncmp用 */ int main(void) {  int i;  FILE *fp, *fo; /* ファイルポインタ用 */  unsigned char buf[10]; /* 文字列比較用 */  int bufp; /* buff用インデックス */  int ch;/* 文字入力用 */  int wflag=0; /* 書き込みフラグ 1=書く 0=書かない */    if((fp = fopen("in.txt", "r")) == NULL){ /* 入力ファイルオープン */   printf("入力ファイルがオープンできません\n");   return -1; /* 強制終了 */  }  if((fo = fopen("out.txt", "w")) == NULL){ /* 出力ファイルオープン */   printf("出力ファイルがオープンできません\n");   fclose(fp); /* 入力ファイルクローズ */   return -1; /* 強制終了 */  }  bufp=0; /* bufへの書き込みポイント初期化 */  while((ch = fgetc(fp))!=EOF){ /* ファイルfpから1文字読み込み */   if (bufp<6) { /* バッファに6文字溜まってないとき */    buf[bufp++]=ch;   } else { /* 6文字溜まったとき */    if (strncmp(buf,"目的:",6)==0) wflag=1; /* 6文字比較 */    if (strncmp(buf,"方法:",6)==0) wflag=0; /* 6文字比較 */    if (wflag==1) fputc(buf[0],fo); /* bufの先頭文字を書く */    for (i=0; i<6; i++) buf[i]=buf[i+1]; /* バッファを前にずらす */    buf[bufp-1]=ch; /* 6文字目にchを入れる */   }  }  /* ファイル読み込み後の処理 */  if (strncmp(buf,"目的:",6)==0) wflag=1; /* 6文字比較 */  if (strncmp(buf,"方法:",6)==0) wflag=0; /* 6文字比較 */  if (wflag==1) for (i=0; i<6; i++) fputc(buf[i],fo); /* bufを書き出す */    fclose(fo); /* 出力ファイルクローズ */  fclose(fp); /* 入力ファイルクローズ */  return 0; }

全文を見る
すると、全ての回答が全文表示されます。
  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.5

ちょっと違っていた…。 > 背景や方法についての説明の中に「目的」という語句が見つかったらどうしますか? 目的について書いてある文章の中に「方法」という語句が見つかったらどうしますか?

全文を見る
すると、全ての回答が全文表示されます。
  • tanma3
  • ベストアンサー率58% (14/24)
回答No.4

いろいろ問題はあると思いますが、第一の問題というか、プログラム言語としての問題はANo.1のJaritenCatさんの回答にもあるように、文字コードについて考慮できていないことです。 pop-bombさんが利用している文字コードはShift-JISなのでマルチバイトコードです。 Shift-JISは日本語は2byteで1文字が表現されます。 たとえば"目的"であれば"目"=0x96da,"的"=0x9349と言うコードになります。 ですので、ch1=="目"を置き換えると"ch1==0x96da"となり、1byteの変数に対し、2byte比較するわけですから、イコールとなることはありえないわけです。 1byteづつ読み込む方法を採用するのであれば、ベタな解決策としては char *p_code="目的"などとしておいて、"目的"文字コート格納ポインタ取得し。これに対して"ch==*p_code"となった場合次の1byteを読み込み、"ch==*(p_code+1)"であれば"目"を発見、これを続けていき"ch==*(p_code+3)"まですべて合致していれば"目的"文字列を発見とするといったような方策が取れると思います。 まず、この問題から解決してはいかがですか?

全文を見る
すると、全ての回答が全文表示されます。
  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.3

仕様に関わる基本的な話として、背景や方法についての説明の中に 「目的」という語句が見つかったらどうしますか?

全文を見る
すると、全ての回答が全文表示されます。
  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.2

> ch1=ch2; 何が入っているかわからないch2をch1に代入して、 > if(ch1=="目"&&ch2=="的"){ /*目的の項目だけ書き込む*/ しかも、そのch1を比較に使っている(方法も正しくない)のはまずいです。 ロジックを見直す方がよいと思います。

pop-bomb
質問者

お礼

やり方としては 1文字ずつ文字を読み取って(ch2)、そして次のもじを読み込む前に ch1を今の文字を代入。 そしてch1=方、ch2=法となった時、書き込み開始。 としたかったのですが、センスがないためにうまくいきません。 どのような方法でやればよいのか教えて欲しいです。

全文を見る
すると、全ての回答が全文表示されます。
回答No.1

if(ch1=="目"&&ch2=="的"){ /*目的の項目だけ書き込む*/ がだめですね。 漢字コードについて勉強しなおしましょう。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • ファイル

    AからZまでの文字が何回出力されるか数えるプログラムなのですが、うまく出力されません。 どこを変えればよろしいでしょうか。 #include<stdio.h> #include<stdlib.h> #include<ctype.h> int count[26]; int main(void) { char str[100] = "xyzYZZ\n"; FILE *fp; char *p; int i; char ch; if((fp = fopen("myfile","w")) == NULL){ printf("ファイルを開くことが出来ません"); exit(1); } p = str; while(*p){ if(fputc (*p,fp) == EOF){ printf("ファイル書き込みエラー"); exit(1); } p++; } fclose(fp); if((fp = fopen ("myfile","r")) == NULL){ printf("ファイルを開くことが出来ません"); exit(1); } while((ch == fgetc(fp)) != EOF){ ch = toupper(ch); if( ch >= 'A' && ch <='Z' ) count[ch - 'A']++ ; } for( i=0 ; i<26 ; i++) printf("%c は %d 回出現\n",i + 'A', count[i]); 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'を数えれるようにしてください。御指摘お願いします。

  • ファイルの入出力で困っています(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; } 何度見直しても間違いが見つからず困窮しております。 どうぞ、みなさまのお力をお貸しください! よろしくお願いいたします。

  • ファイル操作

    コマンドライン引数から、データを入力し、入力データ中の数字を'*'文字で置き換え、それ以外の文字をそのまま出力させるプログラムを作るため #include<stdio.h> int main(int argc, char *argv[]){ FILE *fpi,fpo; char ch; if(argc!=3) { fprintf(stderr, "Illegal number of argument.\n"); return(-1); } if((fpi=fopen(argv[1],"r"))==NULL) { fprintf(stderr, "Can't open input file <%s>.\n", argv[1]); return(-1); } if((fpo=fopen(argv[2],"w"))==NULL){ fprintf(stderr, "Can't open output file <%s>.\n", argv[2]); return(-1); } while((ch=fgetc(fpi))!=EOF){ if(ch>=0 && ch<=9){ ch='*'; } } fclose(fpi); fclose(fpo); return 0; } のようなプログラムを書いたのですが、 if((fpo=fopen(argv[2],"w"))==NULL)がimcompitable types in assigment fclose(fpo);がimcompitable types for arguments1 of 'fclose' というようなエラーが出ます。 なぜか教えていただけませんか? また、その他、足りないところがあれば教えていただけませんか?

  • c言 ファイルのオープンについて

    #include <stdio.h> int main(void) { int ch; FILE *fp; char fname[64]; printf("ファイル名:"); scanf("%s",fname); if((fp=fopen(fname,"r"))==NULL) printf("ファイルをオープンできません。\n"); else{ while((ch=fgetc(fp))!=EOF) putchar(ch); fclose(fp); } return(0); } ファイル名は20130603.cで、実行ファイル(exe)と同じディレクトリに入れてあるのに、このプログラムでファイルをオープンできないのです。 このプログラムを実行するために必要なファイルの作成法と、例としてのファイルの内容、実行結果など、教えていただきたいのです。 色々調べてみたのですが、解決法がイマイチ見つかりませんでした。 どうかよろしくお願いします。

  • ファイルの英字を全部小文字に変換して新規テキストに出力

    テキストファイルの英字を全部小文字に変換して新規テキストに出力するプログラムをつくりましたがうまくいきません。なにがいけないですか? #include <stdio.h> #include <stdlib.h> #include <ctype.h> #define STR_MAX 256 int main(void) { FILE *fi, *fo; /* ファイルポインタ用 */ char fin[100], fout[100]; /* ファイル名用 */ char buff[STR_MAX], *q; /* 文字列用 */ printf("入力ファイル名 : "); /* プロンプト表示 */ gets(fin); /* ファイル名入力 */ printf("出力ファイル名 : "); /* プロンプト表示 */ gets(fout); /* ファイル名入力 */ q = buff;   /* 入力ファイルオープン */ if((fi = fopen(fin, "r")) == NULL){ printf("入力ファイルがオープンできません\n"); exit(1); /* 強制終了 */ }   /* 出力ファイルオープン */ if((fo = fopen(fout, "w")) == NULL){ printf("出力ファイルがオープンできません\n"); exit(1); /* 強制終了 */ } while(fgets(buff, STR_MAX, fi) != NULL){ /* 1行読み込み */ *q = tolower(*q); ++q; fprintf(fo, "%s", buff); /* 1行出力 */ } fclose(fi); /* 入力ファイルクローズ */ fclose(fo); /* 出力ファイルクローズ */ return(0); }

  • ファイルの入出力を行っての文字列反転

    入力した文字列を反転させて出力したいのですが どうしたらよいでしょうか? #include <stdio.h> #include <stdlib.h> #include <string.h> /* 定数 */ #define DELIMITER "/ ," /* 区切り文字 */ int main(void) { FILE *fin,*fout; char infile[40],outfile[40],s[256],s2[256]; char *token; char *strch[50]; int count = 0; int i; printf("入力ファイル名="); gets(infile); printf("出力ファイル名="); gets(outfile); if( (fin=fopen(infile,"r"))==NULL) { /* 入力ファイルオープン */ printf("入力ファイルがオープンできません\n"); exit(EXIT_FAILURE); } if( (fout=fopen(outfile,"w"))==NULL) { /* 出力ファイルオープン */ printf("出力ファイルがオープンできません\n"); exit(EXIT_FAILURE); } while(fgets(s,256,fin)!=NULL) { /* 入力ファイルから読み込んだデータを */ token = strtok(s, DELIMITER); while (token != NULL) { strch[count] = token; token = strtok(NULL, DELIMITER); count++; } for(i = count; i > 0; i--) { strcat(s2, strch[i]); } fputs(s2,fout); /* 出力ファイルに書き込み */ } fclose(fin); /* 入力ファイルクローズ */ fclose(fout); /* 出力ファイルクローズ */ return 0; }

  • ファイル入出力について

    次のようなプログラムを作りました。 コマンドラインから二つのファイルの名前を読み取り、最初の引数のファイルを2番目の引数のファイルにコピーするプログラムです。 質問は下のプログラムのコメント /*この行が質問です*/ の所です。 //ファイルをコピーする の部分の始めに while(!feof(from)) という条件を書いているため、/*この行が質問です*/ の行は不要であると思いましたが、実際にこの一行をのぞいてコンパイルして実行したところ、日本語が文字化けしてコピーされてしまいました。その後、この行を追加してコンパイルして実行すると文字化けもなく実行できました。 なぜこの行が必要なのでしょうか。 よろしくお願いします。 //ファイルコピー #include<stdio.h> #include<stdlib.h> int main(int argc, char *argv[]) {   FILE *from, *to;   char ch;   //引数の数の確認   if (argc != 3) {     printf("引数の数が違います");     exit(1);   }   //コピー元ファイルを開く   if ((from = fopen(argv[1],"r")) == NULL ) {     printf("コピー元ファイルオープンエラー");     exit(1);   }   //コピー先ファイルを開く   if ((to = fopen(argv[2],"w") )== NULL ) {     printf("コピー先ファイルオープンエラー");     exit(1);   }   //ファイルをコピーする   while (!feof(from)) {     ch = fgetc(from);     if(ferror(from)) {       printf("コピー元ファイル読み込みエラー");       exit(1);     }     if (!feof(from))       /*この行が質問です*/       fputc(ch,to);     if (ferror(to)) {       printf("コピー先ファイル書き込みエラー");       exit(1);     }   }   if (fclose(from) == EOF) {     printf("コピー元ファイルクローズエラー");     exit(1);   }   if (fclose(to) == EOF) {     printf("コピー先ファイルクローズエラー");     exit(1);   }   return 0; }

  • 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」だけを読み込んでくれるのかと思ったのですが、数値は正しく表示されません。 以上教えていただければ嬉しいです。

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

    ご覧いただきありがとうございます。 数値を入力して、数値を出力する方法を教えて頂きたいです。 ・   ・   ・ fp = fopen( "a.txt", "a" ); for( i = 16383; i >= 0; i-- ) { fprintf( fp, "%d", i ); } fclose( fp ); ・   ・   ・ data = (int *)malloc(32768); fp = fopen( "a.txt", "r" ); for( i = 0, i <= 16383; i++ ) { fscanf( fp, "%d", data+i ); } fclose( fp ); ・   ・ ・ 以上の記述で、入力はうまくいくのですが、出力の際に数値でなくなってしまいます。どうしてでしょうか? ご存じの方がおりましたら、ご回答よろしくお願いいたします。