• ベストアンサー

修正箇所の指摘のお願い(文字列の書き出し)

C++についての質問です。 あるテキストファイルを読み込み、行頭の空白文字(スペース)を 削除して、別のテキストファイルへ書き出すプログラムを 作成しています。 下記のようにコーディングを行いましたが、 読み込みファイルの1行目が書き出されず、最終行が2回 書き出される状態となってしまいました。 お手数ですが、修正箇所を教えて頂けないでしょうか。 ************************************************************ #include <iostream> #include <string> #include <fstream> using namespace std; #define INPUT_FILE "C:\\input.txt" #define OUTPUT_FILE "C:\\output.txt" int main() { ifstream fin(INPUT_FILE); ofstream fout(OUTPUT_FILE); char str[255]; if(!fin) { cout << "入力ファイルを開けません\n"; return 1; } if(!fout) { cout << "出力ファイルを作成できません\n"; return 1; } fin.getline(str,254); while(!fin.eof()) { std::cin.setf( std::ios::skipws ); // スペースの読み飛ばし fin >> str; fout << str << std::endl; } fin.close(); fout.close(); return 0; } ************************************************************ よろしくお願いします。

  • k2fh
  • お礼率75% (9/12)

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

  • ベストアンサー
  • hidebun
  • ベストアンサー率50% (92/181)
回答No.3

finのEOFチェックを、データ取得直後にしたら。 while(1) { fin >> str; if( fin.eof() ) { break; } fout << str << std::endl; } ってな感じに。

k2fh
質問者

お礼

記載して頂いた内容で解決に至りました。 ありがとう御座いました。

その他の回答 (2)

  • koko_u_
  • ベストアンサー率18% (459/2509)
回答No.2

よく考えたら、operator>> はデフォルトで先頭のスペースをスキップするので setf する必要もないような気がする。 >このプログラムでは、テキストの最後に改行コード >が含まれていると、最終行が2回書き出されてしまいます。 改行も空白文字だから、fin >> str した時に一文字も str に書き込まれずに、前回の内容が残っているのでしょう。多分。 正直、operator>> で単語ごとに読み込むよりも、getline で行単位で読んで自前で空白をカットした方がよいように思います。

k2fh
質問者

お礼

ご回答頂きありがとう御座いました。 getlineを使用しても試していたのですが、 なかなかうまくいかずに困っておりました。 具体的な方法についてお分かりでしたら、 教えて頂けないでしょうか。 よろしくお願いします。

  • koko_u_
  • ベストアンサー率18% (459/2509)
回答No.1

いろいろ置いておいて。。 >fin.getline(str,254); >while(!fin.eof()) >{ > std::cin.setf( std::ios::skipws ); // スペースの読み飛ばし > fin >> str; > fout << str << std::endl; >} 最初に fin.getline() で読んで、while ループで fin >> str ともっかい読んでる。 だいたいなんで std::cin に対して setf してるの? 行の途中に空白があった場合はどうするの?

k2fh
質問者

お礼

ご回答ありがとう御座いました。 すいません、質問を投稿した後に誤りに気づきました。 実際は、下記のプログラムになります。 このプログラムでは、テキストの最後に改行コード が含まれていると、最終行が2回書き出されてしまいます。 if文で改行コード判定すれば良いかと思うのですが、 方法が分かりませんでした。 お手数ですが、解決方法を教えて頂けないでしょうか。 また、行の途中には空白は無いとして考えています。 ******************************* #include <iostream> #include <string> #include <fstream> using namespace std; #define INPUT_FILE "C:\\input.txt" #define OUTPUT_FILE "C:\\output.txt" int main() { ifstream fin(INPUT_FILE); ofstream fout(OUTPUT_FILE); char str[255]; if(!fin) { cout << "入力ファイルを開けません\n"; return 1; } if(!fout) { cout << "出力ファイルを作成できません\n"; return 1; } fin.setf( std::ios::skipws ); // スペースの読み飛ばし while(!fin.eof()) { fin >> str; fout << str << std::endl; } fin.close(); fout.close(); return 0; } ******************************* <上記プログラムの実行例> 読み込むテキスト ---------------- 名前1 名前2 名前3 ---------------- 書き出されるテキスト ---------------- 名前1 名前2 名前3 名前3 ←余計な行が書き出されてしまう ---------------- よろしくお願いします。

関連するQ&A

  • C++の問題で質問です。

    C++のストリームを用いたファイルの入出力の問題です。 #include<iostream> #include<fstream> using namespace std; int main() { ifstream fin; fin.open("test.txt"); if(!fin){ cout<<"Cannot open the file."<<"\n"; exit(1); } char str1[16]; char str2[16]; fin>>str1>>str2; cout<<"Tow words have been written!"<<"\n"; cout<<str1<<"\n"; cout<<str2<<"\n"; fin.close(); return 0; } このプログラムを実行しようとすると In function 'int main()'; 'exit' was not declared in this scope と表示されてしまいます。 どこが間違っているのでしょうか? わかる方がいらっしゃいましたらお願いします。

  • ファイルの読み込みと書き込み

    はじめまして。 最近プログラムを勉強し始めたのですが、ファイルの書き込みと 読み込みで行き詰ってしまいました。 ファイルAで演算したものをファイルBで読み込み表示したいと思い、 以下のようなプログラムを作成したのですが、エラーが出てしまいます。 かなり初歩的なこととは思いますが、アドバイスをお願いします。 【ヘッダファイル(stdafx.h)】 #include <stdio.h> #include <tchar.h> #include <fstream> #include <iostream> 【ソースファイルA】 #include "stdafx.h" using namespace std; int main() { int a; cout << "数値入力:" ; cin >> a; a = a * 2; ofstream fout("sample.txt"); fout << a; fout.close(); return 0; } 【ソースファイルB】 #include "stdafx.h" using namespace std; int main() { ifstream fin("sample.txt"); fin >> a;     fin.close(); int b; b = a; cout << "結果 = " << b << '\n'; return 0; }

  • ファイル入出力で

    現在ファイル入出力の項目をしているのですが、以下の内容で実行すると エラーが出てどうしても実行できません。主にどこを直せばいいのでしょうか? /* ファイルをコピーするプログラム */ #include <stdio.h> int main(void) { FILE *fin, *fout; char infile[40], outfile[40]; char str[256]; printf("コピー元ファイル = "); scanf("%39s", infile); printf("コピー先ファイル = "); scanf("%39s", outfile); if( (fin = fopen(infile, "r") ) == NULL) { printf("Input file open error.\n"); return 1; } if( (fout = fopen(outfile, "w") ) == NULL) { printf("Output file open error.\n"); fclose(fin); return 1; } while(fgets(str, sizeof(str), fin) != NULL) { fputs(str, fout); } fclose(fin); fclose(fout); return 0; } エラーは FILE 、fin, fout,NULLの未定義です。 よろしくお願いします。

  • 文字列入れ替えのプログラムについて

    こんばんは。 文字列入れ替えのプログラムを作っているのですが、分からない部分があるので教えて頂きたいです。 入力ファイルには、 AAAAAAA(必ず7文字)【半角スペース】B(文字数はバラバラ)【tab】C(文字数はバラバラ) というデータが複数入っているものとします。 このファイルを読み込んで、 B【tab】C;;;(セミコロン3つ)AAAAAAA という順に並べ替えるプログラムを作成したいと考えています。 アルゴリズムとしては、 (1)ファイルから1行読み込む (2)読み込んだ行のうち最初の7文字を配列に保存 (3)半角スペースを除き、それ以降(B【tab】C)を出力ファイルに書き込む (4)(2)で保存したものに;;;をつけ、(3)の後ろに書き込む というのを考えていますが、(3)の工程をどうすればいいか分からず困っています。 (改行(\n)までをファイルに書き込めばいいと思うのですが、プログラムでどう書けばいいかが分かりません) よろしくお願いします。 #include<stdio.h> void main(void){ FILE *fin; FILE *fout; char buff[200]; char *p1; char word[200]; int i=0; /*読み込み用ファイルを開く*/ fin = fopen("input.txt", "rt"); if( fin == NULL ){ printf( "File open error1\n" ); return; } /*書き込み用ファイルを開く*/ fout = fopen("output.txt", "wt"); if( fout == NULL ){ printf( "File open error2\n" ); return; } /*1行ずつ読み込む*/ /*読み込める間繰り返す*/ while(fgets(buff,200,fin) != NULL){ i=0; /* buffの先頭アドレスをp1に与える*/ p1=buff; /*工程2:最初から7文字分を配列wordに保存*/ for (i=0;i<7;i++){ word[i]=*p1; *p1++; } /*半角スペース部分をとばし、p1をBの最初の文字にする*/ *p1++;      ここで工程3を行う     /*工程4:保存しておいた文字列を書き込む*/ fprintf(fout,";;;%s\n",word); } fclose(fin); fclose(fout); }

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

    入力した文字列を反転させて出力したいのですが どうしたらよいでしょうか? #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; }

  • ファイル読み込みで一部分書き換えについて

    C++でテキストファイルから先頭の一部分を読み込んで その一部分だけ更新するプログラムを作りたいんですけど どうすればよろしいでしょうか? テキストファイルの中身例(test.txt) AAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAA これを読み込んで ↓↓↓↓↓↓↓↓ たとえば先頭の三文字だけ変えたいとか(test.txt) BJDAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAA これくらいの行数でしたら string s1,s2,s3; fin.open("test.txt"); fin>>s1; fin>>s2; fin>>s3; fin.close(); fout.open("test.txt"); fout<<s1<<"\n"; fout<<s2<<"\n"; fout<<s3<<"\n"; fout.close(); でもなんとかなりそうですけどもっと大量になったときにあまりに 行が長くなりそうなんで他の方法は何かないでしょうか? ちなみに関係あるか分かりませんがコンパイラはVisualC++2005です。

  • ファイル出力"fout"でデータを足して保存するには…

    独学数日目でまだまだ未熟なものですがファイルの出力について、 以下のようなプログラムを作成した場合に… (ソースの断片・部分) //=== int firstfile() { ofstream fout("sample.txt"); if(!fout){ cout << "展開できませんでした\n"; return 1; } else fout <<"最初の書き出し\n"; fout.close(); return 0; } //=== int endfile() { ofstream fout("sample.txt"); if(!fout){ cout << "ファイルの展開に失敗しました。\n"; return 1; } else fout <<"最後の書き出し"; fout.close() return 0; } //=== firstfile(); endfile; firstfile関数で作成したファイルを、 endfile関数でファイルが上書きされてしまい、 「最後の書き出し」 としか出力されません。 「 最初の書き出し 最後の書き出し 」 と文字列を追加して保存できるようにするにはどうやって組めばいいのでしょうか? 持っている本を読みましたがどこにもそれらしい処理方法は書いてありませんでした。

  • C++でのファイル入出力について

    C++で計算したデータを何かファイルに保存しようとしています。 #include<iostream> #include<fstream> using namespace std; int main() { ofstream fout("test0.txt");     //ここで処理をしてファイルに書き込む作業を行う fout.close(); return 0; } 以上のようなサンプルがあったすると、ファイルはカレントディレクトリ に保存されますよね。 そのファイルの保存先を指定するようにするにはどうしたらいいですか? よろしくお願いします。

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

    テキストファイルの英字を全部小文字に変換して新規テキストに出力するプログラムをつくりましたがうまくいきません。なにがいけないですか? #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); }

  • 文字列変換のプログラムについて

    こんにちは。 C言語で以下のようなプログラムを作りたいと考えているのですが、うまく実装できず困っています。 入力ファイルには、【単語(ひらがな)+Tab+その読み(音素列)】が書かれているとします。 例: あいうえお(Tab)a i u e o かきくけこ(Tab)ka ki ku ke ko ・・・ (音素は半角空白で分けられているものとします) このファイルを読み込んで、【単語(ひらがな)+Tab+単語(カタカナ)+Tab+その読み(音素列)】を別のファイルに書き込む  例: あいうえお(Tab)アイウエオ(Tab)a i u e o かきくけこ(Tab)カキクケコ(Tab)ka ki ku ke ko ・・・ というプログラムを作りたいと考えています。 アルゴリズムとして、 (1) ファイルから1行読み込む (2) Tab文字がくるまでの文字列を配列に保存(例でいう「あいうえお」の部分です) (3) Tab文字の次の文字から行末までの文字列を配列に保存(例でいう「a i u e o」の部分です) (4) (2)の1文字ずつをカタカナに変換(ASCIIコードの変換で可能?) (5) (2)(3)(4)を用いて出力用ファイルに書きこむ という流れを考えたのですが、(2)の部分でまず手こずっています。 #include<stdio.h> main(){ FILE *fin; FILE *fout; char buff[200]; char word[200]; int i=0; /*読み込み用ファイルを開く*/ fin = fopen("input.txt", "r"); if( fin == NULL ){ printf( "File open error\n" ); return; } /*書き込み用ファイルを開く*/ fout = fopen("output.txt", "w"); if( fout == NULL ){ printf( "File open error\n" ); return; } /*1行ずつ読み込む*/ /*読み込める間繰り返す*/ while(fgets(buff,200,fin) != NULL){ /*タブ文字がくるまで拾う*/ while(buff[i] != '\t'){ /*文字列を配列wordに保存*/ word[i] = buff[i]; i++; } /*保存できているかの確認*/ printf("%s",word); fclose(fin); fclose(fout); } 実行後、wordの中身が表示されるのですが、 あいうえお,(文字化け)(文字化け) というように、【,(文字化け)(文字化け)】という謎の文字がついてしまいます。 また、入力ファイルの中身が2行以上でも、 あいうえお,(文字化け)(文字化け) あいうえお,(文字化け)(文字化け)・・・ というように、1行目の結果しか出てこないです。 どこを直せばいいのでしょうか? (というかそもそもCよりPerlとかで作ったほうがもっと楽なのかもしれないですが・・・) 教えて頂けると助かります。よろしくお願いします。