0

重複の可能性:
.eof()ループが機能しない

ですから、私はかなり単純なC ++プログラムを持っており、数列のデータを含むテキストファイルを読み取って、それらの行を再フォーマットして別のテキストファイルに出力しようとしています。(再フォーマットには、基本的に、特定の行を取得し、他の行を省略し、各行の最後に少し余分なデータを追加するだけです)。完全に機能しているように見えますが、いくつかの異なるデータファイルでは、特に1行でハングアップし、その1行を無期限に出力し始めるようです。手動でプロセスを停止する必要があります。'fileSize'変数の格納方法に関係していると思います(出力を見ると、繰り返されるfileSizeがその行に対して正しくなく、その行に対応していることがわかります。繰り返し始める前に)。それ以外は、何を探したり修正したりするのかわかりません。この問題に数日間取り組んできました。コードとそれを実行した結果を含めます。任意のアイデアや提案をいただければ幸いです。

コード:

#include <iostream>
#include <fstream>
#include <assert.h>
#include <iomanip>
#include <string>


using namespace std;

int main(int argc, char* argv[]) { 
  //cout << "argc = " << argc << endl; 
  //for(int i = 0; i < argc; i++) 
  //  cout << "argv[" << i << "] = " << argv[i] << endl; 

  ifstream inFile;
  ofstream outFile;

  int numReq, fileSize;
  string lang, dash, langBefore, langAfter;
  string beforeDash, afterDash, beforeNumReq, afterNumReq;
  string beforeFileSize, afterFileSize;

  char fileName[60];
  char outfileName[60];
  char confirm[10];
  char confirm2[10];
  int character;
  char year[5];
  char month[3]; 
  char day[3];
  char hour[3];

  for (int a = 0;a < 60; a++){
    fileName[a] = argv[1][a];
  }

  //fileName = argv[1];


  year[0] = fileName[14];
  year[1] = fileName[15];
  year[2] = fileName[16];
  year[3] = fileName[17];
  year[4] = '\0';

  month[0] = fileName[18];
  month[1] = fileName[19];
  month[2] = '\0';

  day[0] = fileName[20];
  day[1] = fileName[21];
  day[2] = '\0';

  hour[0] = fileName[23];
  hour[1] = fileName[24];
  hour[2] = '\0';

  //cout << "fileName = "<<fileName<<"?"<<endl;
  //cin >>confirm;


  //cout << "So, we have: year = "<<year<<", month = "<<month<<", day = "<<day
  //     <<", and hour = "<<hour<<"?"<<endl;

  inFile.open(fileName);
  assert (!inFile.fail());

  for (int i=0;i<30;i++){  
    outfileName[i] = fileName[i];
  }
  outfileName[29] = '_';
  outfileName[30] = 'O';
  outfileName[31] = 'U';
  outfileName[32] = 'T';
  outfileName[33] = 'P';
  outfileName[34] = 'U';
  outfileName[35] = 'T';
  outfileName[36] = 'p';
  outfileName[37] = 'r';
  outfileName[38] = '.';
  outfileName[39] = 't';
  outfileName[40] = 'x';
  outfileName[41] = 't';
  outfileName[42] = '\0';



  outFile.open(outfileName);
  //Now, add the commands to manipulate the data:

  outFile << fixed << showpoint; 
  outFile << setprecision(2);    

  cout << "Processing data from " << fileName <<" to "<<outfileName<<"."<<endl;

  inFile >> lang;

  cout << "about to begin the 'while' statement." << endl;

  while (!inFile.eof() ){
    string dot (".");
    size_t found;
    found = lang.find(dot); 


    beforeDash = dash;
    beforeNumReq = numReq;
    beforeFileSize = fileSize;

    if (found == string::npos){ //should this be != or == ?

      outFile << lang << " ";

      //*see footnote*

      inFile >> dash >> numReq >> fileSize;
      outFile << numReq << " " << fileSize << " " << year << " " << month
          << " " << day << " " << hour << endl;
      cout <<"Read: "<<lang<<" "<<dash<<" "<<numReq<<" "<<fileSize<<"."<<endl;
      afterDash = dash;
      afterNumReq = numReq;
      afterFileSize = fileSize;      
    }
    else{
      inFile >> dash >> numReq >> fileSize;

      cout <<"Read: "<<lang<<" "<<dash<<" "<<numReq<<" "<<fileSize<<"."<<endl;

      afterDash = dash;
      afterNumReq = numReq;
      afterFileSize = fileSize;

      //      if (beforeFileSize == afterFileSize){ 
      //    cout <<"Why oh why is the afterFileSize = >>" << "<<?" << endl;
      //    cin >> confirm;
      //       }  
    }


    langBefore = lang;
    inFile >> lang;
    langAfter = lang;

    //if (langBefore == langAfter)
    //  cin >>confirm;


  }

  //cout << "after the 'while' statement" << endl;

  inFile.close();
  //assert(!inFile.fail());
  outFile.close();      

  return 0;
}

...そして「./fileIO./fileIOprojectcounts-20091201-100000」の実行からの出力:

./fileIO projectcounts-20091201-100000
Processing data from projectcounts-20091201-100000 to projectcounts-20091201-100000_OUTPUTpr.txt.
about to begin the 'while' statement.
Read: aa - 21 138053.
Read: aa.b - 19 250491.
Read: aa.d - 1 4440.
Read: ab - 56 1324271.
Read: ab.d - 2 21830.
Read: ace - 158 2166792.
Read: af - 5505 55172658.
Read: af.b - 34 528378.
Read: af.d - 429 3378595.
Read: af.n - 1 7290.
Read: af.q - 62 570762.
Read: af.s - 2 14480.
Read: af.v - 2 14340.
Read: ak - 206 3819300.
Read: ak.b - 5 41948.
Read: ak.d - 2 13046.
Read: als - 1294 21339647.
Read: als.b - 23 262665.
Read: als.d - 26 161574.
Read: als.n - 1 7170.
Read: als.q - 14 72963.
Read: am - 431 7073857.
Read: am.d - 19 201112.
Read: am.q - 8 41454.
Read: an - 3084 21488152.
Read: an.d - 127 888272.
Read: ang - 466 7408138.
Read: ang.b - 41 282335.
Read: ang.d - 104 742003.
Read: ang.q - 14 91779.
Read: ang.s - 3 13748.
Read: ar - 62379 1279758510.
Read: ar.b - 384 8037892.
Read: ar.d - 824 8155089.
Read: ar.n - 265 3874251.
Read: ar.q - 194 1812685.
Read: ar.s - 1262 29202150.
Read: ar.v - 1 7170.
Read: arc - 169 2917934.
Read: arc.d - 2 14340.
Read: arz - 1059 18451346.
Read: arz.d - 1 7170.
Read: as - 94 1878525.
Read: as.b - 21 345858.
Read: as.n - 1 7170.
Read: ast - 932 13396685.
Read: ast.b - 21 118692.
Read: ast.d - 131 1049840.
Read: ast.n - 1 7170.
Read: ast.q - 16 95484.
Read: ast.s - 1 7170.
Read: av - 72 1164965.
Read: ay - 151 2382396.
Read: ay.b - 20 252200.
Read: ay.d - 11 76045.
Read: ay.q - 1 7180.
Read: az - 4060 56547487.
Read: az.b - 55 760781.
Read: az.d - 90 777134.
Read: az.q - 40 258399.
Read: az.s - 49 407367.
Read: az.v - 2 14350.
Read: ba - 190 4256164.
Read: ba.b - 5 26948.
Read: ba.d - 2 6709.
Read: bar - 728 13597602.
Read: bar.d - 1 7290.
Read: bat-smg - 967 9405911.
Read: bat-smg.d - 2 14576.
Read: bcl - 262 4076171.
Read: be - 4162 54603077.
Read: be-x-old - 3322 60275040.
Read: be-x-old.d - 2 14350.
Read: be.b - 35 636805.
Read: be.d - 36 317993.
Read: be.n - 2 14462.
Read: be.q - 19 149051.
Read: beta.v - 600 4360526.
Read: bg - 34459 574849813.
Read: bg.b - 197 3226803.
Read: bg.d - 5570 60366778.
Read: bg.n - 40 413897.
Read: bg.q - 560 4307046.
Read: bg.s - 64 863653.
Read: bh - 111 2191650.
Read: bh.d - 3 18855.
Read: bi - 100 2133903.
Read: bi.b - 4 34733.
Read: bi.d - 1 4575.
Read: bm - 90 1441605.
Read: bm.b - 9 25871.
Read: bm.d - 6 43046.
Read: bm.q - 5 26033.
Read: bn - 5509 77859066.
Read: bn.b - 10 150663.
Read: bn.d - 21 216131.
Read: bn.s - 113 1110252.
Read: bo - 226 4894572.
Read: bo.b - 14 222210.
Read: bo.d - 5 33491.
Read: bo.q - 1 7170.
Read: bpy - 2434 42007534.
Read: bpy.b - 1 7180.
Read: br - 4559 33243202.
Read: br.b - 1 7170.
Read: br.d - 297 2117972.
Read: br.q - 13 90504.
Read: bs - 10316 106662123.
Read: bs.b - 48 752610.
Read: bs.d - 136 1136090.
Read: bs.n - 121 987922.
Read: bs.q - 696 5332854.
Read: bs.s - 63 781599.
Read: bug - 84 1047713.
Read: bxr - 37 557388.
Read: ca - 28059 363534831.
Read: ca.b - 332 5455385.
Read: ca.d - 938 7722199.
Read: ca.n - 226 2408335.
Read: ca.q - 272 1806660.
Read: ca.s - 289 2114361.
Read: ca.v - 3 21510.
Read: cbk-zam - 307 7825246.
Read: cdo - 97 1299726.
Read: ce - 253 8919027.
Read: ceb - 2186 21116711.
Read: ceb.d - 3 21750.
Read: ch - 215 2847349.
Read: ch.b - 6 26667.
Read: ch.d - 3 23261.
Read: cho - 15 76754.
Read: cho.d - 1 1972.
Read: chr - 86 1428755.
Read: chr.d - 14 103309.
Read: chy - 19 183064.
Read: chy.d - 1 7170.
Read: ckb - 202 3931545.
Read: closed-zh-tw - 2 14301.
Read: co - 528 7662925.
Read: co.b - 38 2934634.
Read: co.d - 59 498919.
Read: co.q - 11 58046.
Read: commons - 354 270316.
Read: commons.m - 304277 270316.
Read: commons.m - 304277 270316.
Read: commons.m - 304277 270316.
Read: commons.m - 304277 270316.
Read: common^C
4

1 に答える 1

4

問題は次のとおりです。

  1. あなたはinFile.eof()間違った状態を使用しています!ファイルからの読み取りの失敗がEOFに到達したことが原因である場合、この主な用途はエラーを報告eof()ません。
  2. ファイルの読み取りが成功したかどうかを読み取ったはチェックせず、ある時点で失敗したようです。ストリームからの読み取りが失敗すると、std::ios_base::failbitセットを取得し、このビットがクリアされるまでそれ以上の読み取りが成功しないようにします。

ファイルから読み取る正しい方法は次のようになります。

while (inFile >> v0 >> v1 >> v2) {
    process(v0, v1, v2);
}

または、1つのステートメントですべての入力を実行できない場合は、それらを分割して、ループの状態読み取り値を処理する前にファイルのステータスを確認することができます。

while (inFile) {
    inFile >> v0 >> v1 >> v2;
    if (inFile) {
        process(v0, v1, v2);
    }
}

明らかに、他の入力関数を使用することもできますが、たとえば、読み取りが成功したことを読み取ったstd::getline()でも確認する必要があります。

于 2012-10-18T07:07:20.150 に答える