3

I am looking for some advice.

My situation:

  • Application works with text local file.

  • In file are somewhere tags like this:

    correct = "TEXT"
    . Unfortunatelly, there can be unlimited spaces between correct, = and "TEXT".

  • Obtained text is testing in function and may be replaced (the change must be stored in the file).

     correct = "CORRECT_TEXT"

My current theoretical approach:

  • With ofstream -- read by line to string.

  • Find tag and make change in string.

  • Save strings as lines to the file.


Is there some simplify way (with iterators?) in C++ with using standard system libraries only (unix).

Thank you for your ideas.

4

4 に答える 4

4

以下を使用する可能な解決策を次に示します。

例:

#include <iostream>
#include <fstream>
#include <iterator>
#include <algorithm>
#include <string>
#include <vector>

struct modified_line
{
    std::string value;
    operator std::string() const { return value; }
};
std::istream& operator>>(std::istream& a_in, modified_line& a_line)
{
    std::string local_line;
    if (std::getline(a_in, local_line))
    {
        // Modify 'local_line' if necessary
        // and then assign to argument.
        //
        a_line.value = local_line;
    }
    return a_in;
}

int main() 
{
    std::ifstream in("file.txt");

    if (in.is_open())
    {
        // Load into a vector, modifying as they are read.
        //
        std::vector<std::string> modified_lines;
        std::copy(std::istream_iterator<modified_line>(in),
                  std::istream_iterator<modified_line>(),
                  std::back_inserter(modified_lines));
        in.close();

        // Overwrite.
        std::ofstream out("file.txt");
        if (out.is_open())
        {
            std::copy(modified_lines.begin(),
                      modified_lines.end(),
                      std::ostream_iterator<std::string>(out, "\n"));
        }
    }

    return 0;
}

行の操作がどうあるべきか正確にはわかりませんが、使用できます:

編集:

一度にすべての行をメモリに保存することを避けるために、最初の部分copy()を別のファイルに書き込むように変更し、その後に file を書き込むことができますrename():

std::ifstream in("file.txt");
std::ofstream out("file.txt.tmp");

if (in.is_open() && out.open())
{
    std::copy(std::istream_iterator<modified_line>(in),
              std::istream_iterator<modified_line>(),
              std::ostream_iterator<std::string>(out, "\n"));

    // close for rename.
    in.close();
    out.close();

    // #include <cstdio>
    if (0 != std::rename("file.txt.tmp", "file.txt"))
    {
        // Handle failure.
    }
}
于 2012-05-31T15:20:08.887 に答える
1

タスクを小さな部分に分割し、C++でそれぞれを実行する方法を理解することができます。

  • 入力ストリームとしてファイルを開く
  • 一時ファイルを出力ストリームとして開く
  • ストリームから行を読み取る
  • ストリームに行を書き込む
  • 与えられたパターンに線を一致させる
  • 行のテキストを置き換える
  • ファイルの名前を変更する

注:この場合、一度に複数の行をメモリに格納する必要はありません。

于 2012-05-31T15:31:30.900 に答える
1

「INI ファイル」の構文によく似ています。あなたはそれを検索することができ、あなたはたくさんの例を持っているでしょう. ただし、実際に C++ stdlib を使用するものはほとんどありません。

ここにいくつかのアドバイスがあります。(nb、置換する必要があるすべての行は次の構文を使用していると思います<parameter> = "<value_text>":)

  • メソッドを使用std::string::findして「=」文字を見つけます。
  • メソッドを使用してstd::string::substr、文字列を異なるチャンクに分割します。
  • 文字列の前後にあるすべての空白文字を削除するには、トリム アルゴリズムを作成する必要があります。(標準関数で実行できます)

これで、文字列を分割してパーツを分離し、それらを比較して必要な変更を行うことができます。

楽しんで !

于 2012-05-31T16:10:52.333 に答える
0

C ++内でこれを行う必要がありますか?Unixを使用しているのでsed、次のようなコマンドを使用して、これを簡単に実行できるように呼び出すことができます。

cat oldfile | sed 's/\(correct *= *\)\"TEXT\"/\1\"CORRECT_TEXT\"/' > newfile

必要に応じて、C ++内からunixコマンドを呼び出すことができます(たとえば、system("command")fromを使用し<cstdlib>ます。

于 2012-05-31T15:38:44.210 に答える