C++ - 在文本文件中查找和替换(标准系统库)

C++ - Find and replace in text file (standard system libraries)

本文关键字:替换 标准 系统库 查找 文本 文件 C++      更新时间:2023-10-16

我正在寻找一些建议。

我的情况:

  • 应用程序适用于文本本地文件

  • 在文件中的某个地方是这样的标签:

    正确="文本"。
    不幸的是,正确="文本"之间可以有无限的空格。
  • 获取的文本正在测试功能,可以替换(更改必须存储在文件中)。

    正确 ="CORRECT_TEXT"

我目前的理论方法:

  • 使用 ofstream -- 按行读取到字符串。

  • 查找标签并在字符串中进行更改。

  • 将字符串作为行保存到文件中。


C++仅使用标准系统库(unix),是否有一些简化的方法(使用迭代器?

谢谢你的想法。

下面是一个可能的解决方案,它使用:

  • std::getline()
  • std::copy()
  • istream_iterator
  • ostream_iterator
  • vector

例:

#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;
}

我不确定线条的操作应该是什么,但您可以使用:

  • std::string::find()std::string::substr()
  • boost::split()

编辑:

为了避免一次将每一行都存储在内存中,初始copy()可以更改为写入替代文件,后跟文件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.
    }
}
您可以将

任务分成小块,并找出如何在C++中完成每个部分:

  • 打开文件作为输入流
  • 将临时文件作为输出流打开
  • 从流中读取一行
  • 将一行写入流
  • 将线条与给定模式匹配
  • 替换一行中的文本
  • 重命名文件

注意:在这种情况下,您不需要一次在内存中存储多行。

它看起来很像"INI 文件"语法。你可以搜索它,你会有大量的例子。但是,他们中很少有人会真正使用C++stdlib。

这里有一些建议。(注我假设您需要替换的每一行都使用以下语法:<parameter> = "<value_text>"

  • 使用 std::string::find 方法查找"="字符。
  • 使用 std::string::substr 方法将字符串拆分为不同的块。
  • 您需要创建一个修剪算法来删除字符串前面或后面的每个空白字符。(可以使用标准功能完成)

有了所有这些,您就可以拆分字符串并隔离零件以比较它们进行所需的修改。

玩得愉快!

您确定需要在C++内执行此操作吗?由于您使用的是Unix,因此您可以调用sed,该命令可以使用以下命令轻松执行此操作:

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

如果有必要,您可以从C++中调用 unix 命令(例如,使用 <cstdlib> 中的 system("command")