在 C++ 中,从文件找到一行后从该位置复制到该文件的末尾

copying after a line has been found from a file from that position till the end of that file in c++

本文关键字:文件 位置 一行 复制 C++      更新时间:2023-10-16

我有一个文件,其中包含蛋白质坐标以及它前面的其他信息。我的目标是查找名为"$PARAMETERS"的某一行,然后从那里复制它之后的每一行,直到文件末尾。

我怎样才能完成呢?这是我编写的整个程序的一部分小代码(这是其他人几年前编写的,我接手升级了他的代码以进行研究):

ifstream InFile;
InFile.open (DC_InFile.c_str(), ios::in);
while ( not InFile.eof() )
{
    Line = NextLine (&InFile);
    if (Line.find ("#") == 0) continue;   // skip lines starting with # (comments)
    if (Line.length()   == 0) continue;   // skip empty lines
    size_t pos = Line.find("$PARAMETERS");
    Line.copy(Line.begin("$PARAMETERS")+pos, Line.end("$END"));
    &Line.copy >> x_1 >> y_2 >> z_3;
}

请记住,我将行定义为string

我想你需要在$PARAMETERS$END之间读取数据,而不是从$PARAMETERS到文件末尾。如果是这样,您可以使用以下代码:

string str;
while (getline(InFile, str))
{
    if (str.find("#") == 0)
        continue;
    if (str.length() == 0)
        continue;
    if (str.find("$PARAMETERS") == 0)
    {
        double x_1, y_2, z_3; // you want to read numbers, i guess
        while (getline(InFile, str))
        {
            if (str.find("$END") == 0)
                break;
            stringstream stream(str);
            if (stream >> x_1 >> y_2 >> z_3)
            {
                // Do whatever you want with x_1, y_2 and z_3
            }
        }
    }
}

这将处理多个数据部分;不确定您是否真的需要此行为。

例如:

# comment
$PARAMETERS
1 2 3
4 5 6
$END
#unrelated data
100 200 300
$PARAMETERS
7 8 9
10 11 12
$END

我不确定你想要复制文件的第一行是什么,但假设你明白了,并且你没有阅读超过当前行的内容,你可以像这样复制你正在阅读的 fike 的尾巴:

out << InFile.rdbuf();

此处out是您要将数据发送到的std::ostream

请注意,您不应该使用InFile.eof()来确定是否有更多数据!相反,您应该读取要读取的内容,然后检查读取是否成功。您需要在阅读后进行检查,因为流在您这样做之前无法知道您尝试阅读的内容。

跟进迪特马尔的回答:在我看来,这听起来像你应该使用std::getline,直到找到一行匹配您的模式。 如果您希望该行作为您的输出,然后输出它,然后使用 Dietmar 的解决方案复制文件的其余部分。 像这样:

while ( std::getline( in, line ) && ! isStartLine( line ) ) {
}
if ( in ) {         //  Since you might not have found the line
    out << line << 'n';    //  If you want the matching line
                            //  You can also edit it here.
    out << in.rdbuf();
}

并且不要放各种复杂的解析信息,与continuebreak,在循环中。 结果是两者不可读且不可维护。 将其分解为一个简单的功能,如上所述:您还将有更好的机会获得没错。 (就您而言,您应该匹配"$PARAMETERS # xxx",还是不匹配? 在单独的函数中,更容易获得没错。