2017-01-18 16 views
-1

空の行を含む可能性のあるテキストファイルがあります。私はこのファイルを開き、空の行を探したい。空の行が存在する場合は、その行を削除します。 私はこの目的のために一時ファイルを作成したくありません。後で同じファイルを編集して閉じたいと思っています。空の行をC++のテキストファイルから削除します

私はすでに同様の問題についていくつかの記事を見てきましたが、どれも私のために働いていませんでした。

void DeleteEmptyLines(const string& FilePath) 
{ 
    //EXISTING File 
    std::fstream FileStream; 
    std::string CurrentReadLine; 
    if (doesFileExist(FilePath)) 
    { 
     FileStream.open(FilePath, std::fstream::in | std::fstream::out | std::fstream::app); 

     //Read all the lines till the end of the file 
     while(getline(FileStream, CurrentReadLine)) 
     { 
      //Check if the line is empty 
      if(CurrentReadLine.empty()) 
      { 
       cout<<"Empty line found"<<endl; 
       //DELETE THIS EMPTY LINE 
      } 
     } 

     FileStream.clear(); 
     FileStream.close(); 
    } 
    // else --->> do nothing 
} 

現在のファイル(MyFile.txtを):

Line1 

Line2 

Line3 

私は(MyFile.txtを)必要なもの:

Line1 
Line2 
Line3 

PS:私はVS2010を使用していますWindowsマシン上。

+0

私はあなたに答えがありません。上記のコードでは、1つ以上のスペースのある行だけが空ではないと考えてください。それは目的ですか?扱うファイルが決して大きすぎない場合は、メモリ内に新しいファイルを最初に作成し、空の行を残しておくことができます。例のようにhttp://www.cplusplus.com/reference/string/string/empty/ – diidu

+0

いいえ、私の目的は、文字を持たない行をすべて削除することです。 – skm

+0

これは動作しますか?最初にすべてを読む - >データを処理する - >新しいデータをファイルにダンプする(今度は "w"モードで開く) – Icarus3

答えて

1

シンプルなソリューション。空の行をスキップしてstringにファイルを読み込み、ファイルをstringの内容で上書きします。

void DeleteEmptyLines(const std::string &FilePath) 
{ 
    std::ifstream in(FilePath); 
    std::string line, text; 
    while (std::getline(in, line)) 
     if !(line.empty() || line.find_first_not_of(' ') == std::string::npos) 
      text += line + "\n" 
    in.close(); 
    std::ofstream out(FilePath); 
    out << text; 
} 

EDIT:あなたが述べたようにあなたが投稿 @skm新しい答えは、空のスペースを含む行を消去されません。ラインが「空」でないことを確認するために、この用途にこの状況を解決するために

!(CurrentReadLine.empty() || CurrentReadLine.find_first_not_of(' ') == std::string::npos) 
0

データが連続して保存されるため、現在使用されているすべてのファイルシステムで実行することはできません。したがって、ファイルからいくつかのバイトを '削除'するには、後続のすべてのバイトをそのバイト数で移動する必要があります。そして、あなたは読書のためにファイルを開くことができず、その瞬間にそれを最初から書き直します。

だからあなたは3つのオプションがあります。

  1. をメモリにすべてのファイルを読み、[空行をスキップして、元の ファイルに行を書き換えます。

  2. 空の行を の空でない行だけを保存してから、同じファイルに書き込んでください。送信元と送信先が 同じである場合は、RAMやファイルの移動操作の多くを持っている必要はありません ので、良い選択が実際にある

  3. 使用の一時ファイルは、(ほとんどのファイルシステムで 低コストでありますパーティション)。

+0

ファイルを1行ずつ移動し、最初の空白の後の各行をファイルの最初の正しいバイト数に書き換えて、完了したらそれを切り捨てることができます。 –

+0

コーディングはもっと難しくなりますが、現在の読み取り位置と現在の書き込み位置の両方を追跡しながら、最初から空でない行だけを書き換えることで、読み取り中のファイルも書き直すことができます。 –

+0

@ david-schwartz読み込み時などのバッファリングのために悪影響を及ぼすことはありませんか?メモリ内でそれを行うことはできますが、ファイルについてはわかりません。 – FunkyCat

0

私は、次のように私の機能を変更しました。

void DeleteEmptyLines(const string& FilePath) 
{ 
    std::string BufferString = ""; 

    //File 
    std::fstream FileStream; 
    std::string CurrentReadLine; 
    if (doesFileExist(FilePath)) 
    { 
     FileStream.open(FilePath, std::fstream::in); //open the file in Input mode 

     //Read all the lines till the end of the file 
     while(getline(FileStream, CurrentReadLine)) 
     { 
      //Check if the line is empty 
      if(!CurrentReadLine.empty()) 
       BufferString = BufferString + CurrentReadLine + "\n"; 
     } 
     if(DEBUG) cout<<BufferString<<endl; 
     FileStream.close(); 

     FileStream.open(FilePath, std::fstream::out); //open file in Output mode. This line will delete all data inside the file. 
     FileStream << BufferString; 
     FileStream.close(); 
    } 
    // else --->> do nothing 
} 

この関数は、以下の手順を行います。

  1. オープンを入力モードでファイル
  2. 空ではないすべての行を読むには、再度ファイル
  3. オープンファイルを閉じ出力モード(ファイル内のすべてのデータを削除)
  4. ファイルに文字列を入力
  5. ファイルを閉じます。
関連する問題