从文件中删除前 n 行

时间:2021-01-25 13:08:14

标签: c++ file

我有一个文件,其中包含该学生的学生姓名、ID、年龄和编号。我想读取文件,例如,如果学生人数为 2,则删除与该学生对应的所有 3 个先例行。

我的txt是这样的

<块引用>

马克
45646564
18
1

4563213
21
2
保罗
45654
22
4
爱丽丝
45948
20
5

while (getline(student, line))
{
        if (counter % 4 == 2) { // Here I want to delete all prcedent 3 lines}
}
    

1 个答案:

答案 0 :(得分:0)

不幸的是,您的方法或您的设计理念不是很好。应该稍微改进一下。

您需要开始以面向对象的方式思考。对象“student”具有属性或数据元素,例如“name”、“id”、“age”和“number”。所有这些数据都属于一起,并与特定的“学生”相关。接下来,您需要定义应该对这些数据进行操作的方法,例如“读取”和“写入”某些学生的完整数据。

如果您在阅读完整的“学生”记录后拥有的“数字”属性没问题,那么您将其存储在某种数组中或std::vector

那么,让我们从数据部分开始:

struct Student {
    std::string name{};
    unsigned long id{};
    unsigned int age{};
    unsigned int number{};
};

这将描述一名学生的属性。

接下来,我们确实想对这些数据进行操作。第一个操作是我们确实希望从任何类型的 stream 读取这些数据,例如从控制台 (std::cin) 或从文件 (std::ifstream)。这基本上无关紧要,流就是流:-)

iostream 库具有所谓的“提取器”操作符,用于从流中读取数据。那是 >> 运算符。这我们可以简单地为我们的“学生”结构定义。像这样:

    friend std::istream& operator >> (std::istream& is, Student& s) {
        return std::getline(is >> std::ws, s.name) >> s.id >> s.age >> s.number;
    }

给出了函数的签名。这是正式的要求。然后,现在我们在该函数中做什么。我想提醒大家,istream 提取操作总是返回对给定 istream. 的引用。所以,首先我们调用 std::getline。这将读取学生的姓名,然后再次返回。然后该行看起来像 return is >> s.id >> s.age >> s.number。接下来我们将读取 id。这也将返回。然后语句看起来像 return is >> s.age >> s.number。等等等等。最后,我们将阅读所有内容,只需return is;

std::getline 中,您将看到 >>std::ws。这将忽略所有前导空格,如换行符或其他任何内容。

所以,现在,如果我们有一个打开的文件流,比如说“ifs”和一个名为“student”的学生变量,那么我们可以写ifs >> student,它会从文件中读取一个完整的学生记录文件。所以,所有 4 行。

顺便说一下,我们可以对插入函数 << 做同样的机制。

如果我们现在循环运行并将读取的学生数据存储到 std::vector 中,我们可以从文件中复制所有数据。

或者,如果一个学生有某个属性,那么我们也可以决定不复制数据。

这可能看起来像:

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

struct Student {
    std::string name{};
    unsigned long id{};
    unsigned int age{};
    unsigned int number{};

    friend std::istream& operator >> (std::istream& is, Student& s) {
        return std::getline(is >> std::ws, s.name) >> s.id >> s.age >> s.number;
    }
    friend std::ostream& operator << (std::ostream& os, const Student& s) {
        return os << s.name << '\n' << s.id << '\n' << s.age << '\n' << s.number << '\n';
    }
};

int main() {


    // Here we will store all our studends
    std::vector<Student> students{};

    // Open the file with the data
    std::ifstream ifs("r:\\data.txt");

    // Check, if the file could be opened.
    if (ifs) {

        Student tempStudent{};
        
        // Read all students from a file, until we hit eof or some other problem
        while (ifs >> tempStudent) {

            // if the student does fullfill the requirements, then we take it, else not
            if (tempStudent.number != 2)
                students.emplace_back(std::move(tempStudent));

        }

        // OK, for debug purposes we show all data ion the screen
        for (const Student& s : students)   std::cout << s << '\n';
    }
    else std::cerr << "\n\nError: source file could not be opened\n\n";
    return 0;
}


如果您想查看更高级的 C++ 解决方案,请查看以下内容:

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

struct Student {
    std::string name{};
    unsigned long id{};
    unsigned int age{};
    unsigned int number{};

    friend std::istream& operator >> (std::istream& is, Student& s) {
        return std::getline(is >> std::ws, s.name) >> s.id >> s.age >> s.number;
    }
    friend std::ostream& operator << (std::ostream& os, const Student& s) {
        return os << s.name << '\n' << s.id << '\n' << s.age << '\n' << s.number << '\n';
    }
};

int main() {

    // Here we will store all our studends
    std::vector<Student> students{};

    // Open the file with the data and check, if it is open
    if (std::ifstream ifs("r:\\data.txt");ifs) {

        // Read all data
        std::copy_if(std::istream_iterator<Student>(ifs), {}, std::back_inserter(students), [](const Student& s) {return s.number != 2;});

        // For debug purposes we show all data ion the screen
        std::copy(students.begin(), students.end(), std::ostream_iterator<Student>(std::cout, "\n"));
    }
    else std::cerr << "\n\nError: source file could not be opened\n\n";
    return 0;
}
相关问题