- 締切済み
ファイルの入出力に関する質問
ファイルに書かれたテキストから一部分だけを抜き出し、 それを再び別のファイルに書き込むプログラムを作成したいのですが、 書き込んだファイルの中身が何もないという事態に陥りました。 プログラムは以下の通りです。 #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); } ちなみに抜き出す前のファイルは 「背景:近年、日本経済において・・・<中略>・・・目的:本研究では・・・・・・方法:本研究では・・・・・背景:最近、アメリカ市場における・・・目的:今年度における・・・方法:・・・」 のように改行されずに入力されており、 そこから、目的の事項だけを取り出し 「目的:本研究では・・・<中略>・・・。目的:今年度における・・・」 のようなファイルを作りたいと思っています。 どうかご教授ください。
- みんなの回答 (6)
- 専門家の回答
みんなの回答
- JaritenCat
- ベストアンサー率37% (122/322)
とりあえず、「目的:」と「方法:」を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% (2127/6289)
ちょっと違っていた…。 > 背景や方法についての説明の中に「目的」という語句が見つかったらどうしますか? 目的について書いてある文章の中に「方法」という語句が見つかったらどうしますか?
- tanma3
- ベストアンサー率58% (14/24)
いろいろ問題はあると思いますが、第一の問題というか、プログラム言語としての問題は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% (2127/6289)
仕様に関わる基本的な話として、背景や方法についての説明の中に 「目的」という語句が見つかったらどうしますか?
- asuncion
- ベストアンサー率33% (2127/6289)
> ch1=ch2; 何が入っているかわからないch2をch1に代入して、 > if(ch1=="目"&&ch2=="的"){ /*目的の項目だけ書き込む*/ しかも、そのch1を比較に使っている(方法も正しくない)のはまずいです。 ロジックを見直す方がよいと思います。
- JaritenCat
- ベストアンサー率37% (122/322)
if(ch1=="目"&&ch2=="的"){ /*目的の項目だけ書き込む*/ がだめですね。 漢字コードについて勉強しなおしましょう。
お礼
やり方としては 1文字ずつ文字を読み取って(ch2)、そして次のもじを読み込む前に ch1を今の文字を代入。 そしてch1=方、ch2=法となった時、書き込み開始。 としたかったのですが、センスがないためにうまくいきません。 どのような方法でやればよいのか教えて欲しいです。