【问题标题】:how to replace a line with another/ c++ code如何用另一个/ C++代码替换一行
【发布时间】:2012-01-13 13:21:25
【问题描述】:

我正在开发 ubuntu。我有一个名为 test.txt 的文件。我想用另一行替换第二行。我怎样才能做到这一点?我不想创建一个新文件并删除第一个文件。

我想指定新行的长度与第一个的长度相同

【问题讨论】:

  • 你想用另一行长度完全相同的行替换该行吗?
  • 是的!新线的长度与第二条的长度相同
  • @AngelDream: 是纯 ASCII 还是你在这行中有 UTF-8 序列?

标签: c++ linux file-io


【解决方案1】:

尝试类似:

#include <fstream>
#include <string>

int main() {
    const int lineToReplace = 14;
    std::fstream file("myfile.txt", std::ios::in | std::ios::out);
    char line[255];
    for (int i=0; i<lineToReplace-1; ++i) 
        file.getline(line, 255); // This already skips the newline
    file.tellg();
    file << "Your contents here" << std::endl;
    file.close();
    return 0;
}

请注意,line 最多可容纳 254 个字节(加上空终止符),因此如果您的行占用更多字节,请进行相应调整。

【讨论】:

  • 如何更改此项以替换第 14 行?
  • 把getline放在一个循环中执行13次:for (int i=0; i&lt;13; ++i) file.getline(line, 255);;
  • 它不;不改变新行
【解决方案2】:

如果文件足够小,您可以将其读入内存,对内存中的副本进行任何您想要的修改,如果退出则写入。

编辑要求的代码:

// A vector to store all lines
std::vector<std::string> lines;

// The input file
std::ifstream is("test.txt")

// Get all lines into the vector
std::string line;
while (std::getline(is, line))
    lines.push_back(line);

// Close the input file
is.close();

// All of the file is now in memory, each line a single entry in the vector
// "lines". The items in the vector can now be modified as you please.

// Replace the second line with something else
lines[1] = "Something else";

// Open output file
std::ofstream os("test.txt");

// Write all lines to the file
for(const auto& l : lines)
    os << l << '\n';

// All done, close output file
os.close();

【讨论】:

  • 要获取内存中的文件,您可以使用stat(2) 系统调用来查询文件的长度,然后使用open(2) 它和mmap(2) 它。有关详细信息,请参阅手册页。
  • @AngelDream 在我的回答中添加了一个简单的示例。
【解决方案3】:

这是 Python,但它的可读性和简洁性明显更高:

f = open('text.txt', 'w+') # open for read/write
g = tempfile.TemporaryFile('w+') # temp file to build replacement data
g.write(next(f)) # add the first line
next(f) # discard the second line
g.write(second_line) # add this one instead
g.writelines(f) # copy the rest of the file
f.seek(0) # go back to the start
g.seek(0) # start of the tempfile
f.writelines(g) # copy the file data over
f.truncate() # drop the rest of the file

您也可以使用shutil.copyfileobj 代替writelines 在文件之间进行块复制。

【讨论】:

  • 这是什么语言?看起来一点也不像 C++。
  • 哦,我什至没有注意到他说的是 c++。我希望看到一个简洁的 C++ 解决方案。 OP 我建议你在 python 中执行此操作。
  • 在类似的不是他要求的静脉中,sed -e '2s/.*/this is definitely the second line/' ~/test_file
  • I don't want to create a new file and delete the first one。这本质上是一样的:它重写了整个文件。更糟糕的是,它首先读取内存中的整个文件,无论大小如何
  • @sehe:嗯,根据他不想写新文件的原因,写一个临时文件然后覆盖原来的文件可能仍然是一个解决方案:如果他只是想要为了避免丢失文件的扩展属性或类似属性,或者让另一个程序保持文件打开并跟踪更改,然后临时文件,然后覆盖方案解决了他的问题。当然,如果他的问题是临时文件本身,那是没有办法的。当然内存问题仍然存在(如果您的文件适合内存,则根本没有理由使用临时文件)。
【解决方案4】:

我会这样做,但对行长没有硬性限制:

#include <fstream>
#include <string>

using namespace std;

int main()
{
    fstream file("test.txt",std::ios::in|std::ios::out);
    string line;
    string line_new="LINE2";

    // Skip the first line, file pointer points to beginning of second line now.
    getline(file,line);

    fstream::pos_type pos=file.tellg();

    // Read the second line.
    getline(file,line);

    if (line.length()==line_new.length()) {
        // Go back to start of second line and replace it.
        file.seekp(pos);
        file << line_new;
    }

    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-09
    • 1970-01-01
    • 1970-01-01
    • 2022-11-18
    • 1970-01-01
    • 2022-12-18
    • 1970-01-01
    相关资源
    最近更新 更多