2017-03-20 23 views
1

ファイルからバッファに読み込み、読み込んだテキストを文字列に分割して、各行が改行して改行し、新しい行にします。ブロックからファイルをブロック単位で読み込み、行単位で行を分割する

はここに私のコードです:

int ysize = 20000; 
char buffer2[ysize]; 
int flag = 0; 
string temp_str; 
vector<string> temp; 
while(fread(buffer2, ysize, 1, fp2)>0){ 
    //printf("%s", buffer2); 
    std::string str(buffer2); 
    //push the data into the vect 
    std::string::size_type pos = 0; 
    std::string::size_type prev = 0; 
    /*means the last read did not read a full sentence*/ 
    if (flag == 1) { 
     if (buffer[0] == '\n') { 
      //this means we have read the last senstense correctly, directly go to the next 
     } 
     else{ 
      if((pos = str.find("\n", prev)) != std::string::npos){ 
       temp_str+=str.substr(prev, pos - prev); 
       temp.push_back(temp_str); 
       prev = pos + 1; 
      } 
      while ((pos = str.find("\n", prev)) != std::string::npos) 
      { 
       temp.push_back(str.substr(prev, pos - prev)); 
       prev = pos + 1; 
      } 

      // To get the last substring (or only, if delimiter is not found) 
      temp.push_back(str.substr(prev)); 

      if (buffer2[19999] != '\n') { 
       //we did not finish readind that query 
       flag = 1; 
       temp_str = temp.back(); 
       temp.pop_back(); 
      } 
      else{ 
       flag = 0; 
      } 


     } 
    } 
    else{ 

     while ((pos = str.find("\n", prev)) != std::string::npos) 
     { 
      temp.push_back(str.substr(prev, pos - prev)); 
      prev = pos + 1; 
     } 

     // To get the last substring (or only, if delimiter is not found) 
     temp.push_back(str.substr(prev)); 

     if (buffer2[19999] != '\n') { 
      //we did not finish readind that query 
      flag = 1; 
      temp_str = temp.back(); 
      temp.pop_back(); 
     } 
     else{ 
      flag = 0; 
     }} 
} 

問題は、これは正しくデータを読み取らないで、それはほとんどのテキストの半分を排除します。

私はここで何が欠けているのか分かりません。私の考えは、データブロックをブロック単位で読み込み、それを1行ずつに分割することです。これは、whileループでハッピングしているものです。私はフラグを使用してオーバーフローケースを処理しています。 にfread魔法のstd ::文字列str(バッファ2)は未定義の動作につながることを意味し、NULLで終了する文字列を、作成しないことを

+2

['while(std :: getline(myFileStream、lineStr)){{}}'(http://en.cppreference.com/w/cpp/string/basic_string/getline) std :: ifstream'を実装しています。 – BoBTFish

+0

私はそれをしましたが、パフォーマンスは恐ろしいものでした。私は、テストしたときに有意差があったが、文字列を分割することが少しジレンマであるパフォーマンスを改善するためにデータブロックを読み込もうとしている。 – user7631183

+0

私はBoBTFishに同意するが、 'std :: regex'または' std :: stringstream'。 –

答えて

1

まずノート、。ですから、あなたが行ずつを読み取るためにfgetsを使用することができますが、ここで実装バッファリングアプローチを避けるために

int nread = 0; 
while((nread =fread(buffer2, ysize-1, 1, fp2)) > 0){ 
    buffer2[nread] = 0; 
    std::string str(buffer2); 
    ...  

ような何かを行う必要があり、その後、あなただけの読み取りバッファより長い行を連結する心配する必要があります。

バッファーの最初の文字が改行で、フラグ== 1の場合は、現在のバッファー全体をスキップし、まだデータがある場合は次のバッファーを読み込みます。 (私はのバッファ[0]であなたは実際にはbuffer2 [0]を意味すると仮定します)。

+0

ありがとう!、私は 'buffer2 [nread] = 0; 'これは常に最後の読み込み文字を削除し、0に置き換えますか? &fgetsは私の問題を解決しません。一度に複数の行を読み込もうとしています。 – user7631183

+1

C/C++ではインデックスが0から始まるため、* nread *文字がバッファに読み込まれると、 * buffer [0] ... buffer [nread-1] *、* buffer [nread] = 0 *を指定すると、NULL終了が保証されます。 * fgets * - はい私はあなたが1つの行に複数の行を読みたいと思っていますが、おそらく* fgets *は後でバッファを分割する手間を省き、* fgets *いくつかのバッファリング、それはあなたがそれを使用してパフォーマンスを失うことはありません可能性があります。 –

関連する問題