1

呼び出されたときに、パラメータに一致するテキストファイルを検索し、ファイルを上書きして「更新」する関数を作成しようとしています。

これが私の現在の機能です:

編集:これは新しい更新されたコードですが、まだ機能していません:/

UpdateGemに送信する行は次のとおりです(例:sTempTxt: "AB:5.55")

ostringstream stream; 
stream << std::setprecision(3)  << fEindgem;
string sTempTxt = sVak + ":" + stream.str() + "\n";
UpdateGem(sTempTxt);

void UpdateGem(string text)
{
     ifstream f;
     f.open("GEM.txt");
     string sGEMS[100];
     string temp[3];
     splitstring(text, ":", temp[0], temp[1]);
     bool OverWrite;
     int count = 0;
     string Delete, line;

     while(true)
     {
         getline(f, sGEMS[count], '\n');
         if(f.eof()) break;
         splitstring(sGEMS[count], ":", temp[1], temp[2]);
         if (temp[0] == temp[1])
         {
              OverWrite = 1;
              Delete = sGEMS[count];
         }
         count++;
     }

// Don't set count to 0, since we need it
// count = 0;
   ofstream f2;
   f2.open("GEM2.txt"/*,std::ios_base::app*/);
   if (OverWrite) 
   {
      f.seekg(0, std::ios::beg);
      for (int i = 0; i < count; ++i) 
      {
         if (sGEMS[i] != Delete) f2 << sGEMS[i];
      }
   }
     f.close();
     f2.close();
     remove("GEM.txt");
     rename("GEM2.txt", "GEM.txt");

     ofstream file;
     file.open("GEM.txt",std::ios_base::app);
     file << text;
     file.close();     


}

置き換える必要のある行はNAME:NUMBERの形式であり、番号は異なる可能性があるため、splitstring関数を使用して名前を見つかった行の名前と比較し、その行を完全に消去して「更新」します。後で再度追加してください。ただし、現在のコードは更新された行のみをファイルに書き込み、古い行は書き込みません...

4

1 に答える 1

0

あなたのプログラムからは、「GEM.txt」に 100 行を超えるテキストはないと想定しているように見えます。ただし、ファイルの最初のスキャンでは、何行読み込まれたか覚えていません。それを補うために、元の「GEM.txt」ファイルを読み直して何行かを覚えようとします。保存した行を「GEM2.txt」に書き出します。

jrokが正しく指摘しているように、2番目のループではfeof、最初のループですでに遭遇した時点から「GEM.txt」から読み取っています。したがって、2 番目のループがループ内に入ることはありません。これはwhilegetline呼び出しが取得するものは何もないと見なしているためです (fファイルの最後にあるため)。whileしたがって、jrok は、2 番目のループの直前に追加するコード行を提供しました。

f.seekg(0, std::ios::beg);

ただし、すべての行が既に配列に保存されているため、sGEMS配列を新しいファイルに直接書き出すことができます。

// Don't set count to 0, since we need it
// count = 0;
ofstream f2;
f2.open("GEM2.txt"/*,std::ios_base::app*/);
if (Overwrite) {
    for (int i = 0; i < count; ++i) {
        if (sGEMS[i] != Delete) f2 << sGEMS[i] << std::endl;
    }
}
//...

ファイルが 100 行を超える場合は、配列を使用する代わりにベクトルを使用する方が安全です。countのサイズで追跡されるため、もう必要ありませんvector

std::vector<std::string> sGEMS;
//...
while (true) {
    getline(f, line);
    if (f.eof()) break;
    sGEMS.push_back(line);
    //...
}

「GEM.txt」ファイルが非常に大きいと予想される場合は、ファイルの処理方法を再考する必要がある場合があります。特に、最初にやろうとしていたように、スキップする行番号だけを覚えて、"GEM.txt" から "GEM2.txt" に行をコピーする必要があります。

最後に、コードの最後の書き込みで、ファイルを追加用に開きますが、出力用には開きません。C++ はこれを、ファイルの内容を破棄したいという意味に解釈します。代わりに、ios_base::outオープン コールにフラグを追加します。

ios_base::openmode mode = ios_base::out|ios_base::app;
file.open("GEM.txt",mode);
file << text << std::endl;
file.close();

しかし、そうする代わりに、f2それを閉じる前に最後にタックすることもできました.

私の提案では、 の最終的な形式は次のようにUpdateGemなります。

void UpdateGem(string text) {
    ifstream f;
    ofstream f2;
    vector<string> sGEMS;
    string temp[3];
    bool OverWrite;
    string Delete, line;

    splitstring(text, ":", temp[0], temp[1]);
    sGEMS.reserve(100);
    f.open("GEM.txt");
    while (true) {
        getline(f, line);
        if (f.eof()) break;
        sGEMS.push_back(line);
        splitstring(line, ":", temp[1], temp[2]);
        if (temp[0] == temp[1]) {
            OverWrite = 1;
            Delete = line;
        }
    }
    f.close();
    f2.open("GEM2.txt"/*,std::ios_base::app*/);
    if (OverWrite) {
        for (int i = 0; i < sGEMS.size(); ++i) {
            if (sGEMS[i] != Delete) f2 << sGEMS[i] << std::endl;
        }
    }
    f2 << text << std::endl;
    f2.close();
    remove("GEM.txt");
    rename("GEM2.txt", "GEM.txt");
}

次のmainプログラムでコードをテストしました。

int main () { UpdateGem("Test:0001"); }

そして、次のように実装されsplitstringています:

bool splitstring (string s, string match, string &a, string &b)
{
    int x = s.find(match);
    if (x != string::npos) {
        a = s.substr(0, x);
        b = s.substr(x+match.size());
        return true;
    }
    return false;
}

次の入力 "GEM.txt" が与えられた場合:

a:x
b:x
Test:1234
c:x

プログラムは、「GEM.txt」の内容を次のように変更します。

a:x
b:x
c:x
Test:0001
于 2012-06-18T04:03:45.357 に答える