繁体   English   中英

如何读取/写入 C++ 中的文件?

[英]How to read/write to a file in C++?

我是 c++ 文件读/写的新手。 请有人帮助我阅读文件的最佳方法,如下所示 ta class 像这样

class Student
{
public:
string fName;
string sName;
int mark

};
// file.txt each data is ends with newline and metadata ends with ';'
Firstname1;SecondName1;Mark1 
Firstname2;SecondName2;Mark2
Firstname3;SecondName3;Mark3
Firstname4;SecondName4;Mark4
Firstname5;SecondName5;Mark5

请有人帮我找到最好的方法

所以,我们这里有两个问题要解决。

  1. 从文件中读取数据
  2. 将读取的数据拆分为其部分

源文本文件的格式称为“CSV”,用于“ C omma S eparated Values”。 可以使用任何其他有意义的分隔符代替逗号。

那么,需要做什么呢?

  • 打开文件并检查是否可以打开
  • 在循环中从文件中逐行读取
  • 将值拆分为各个部分
  • 将零件存储在您的结构中

您面临的挑战是字符串的“拆分”。 有很多很多潜在的解决方案,让我与std::getline分享一种常用的方法。

std::getline基本上从输入 stream 中读取字符并将它们放入字符串中。 读取完成,直到找到分隔符。 如果您没有专门提供分隔符作为输入参数,则假定为 '\n'。 因此,它将从 stream(文件)中读取完整的一行。

然后,由于许多人不理解混合使用格式化和未格式化输入的缺陷,因此将读取行放入std::istringstream中。 这对问题也更加健壮/弹性然后我们可以使用std::getline再次提取字符串的部分。

一个可能的例子是:

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

class Student
{
public:
    std::string fName{};
    std::string sName{};
    int mark{};
};

int main() {

    // Open file and check, if it could be opened
    if (std::ifstream sourceFileStream{ "file.txt" }; sourceFileStream) {

        // The file could be opened. Define a vector, where we store all Student data
        std::vector<Student> students{};

        // Read all lines of the file
        for (std::string line; std::getline(sourceFileStream, line); ) {

            // Put the line into an std::istringstream, to extract the parts
            std::istringstream iss{ line };

            // Define a temporary Student for storing the parts
            Student tempStudent{};

            // Get the parts
            std::getline(iss, tempStudent.fName, ';');
            std::getline(iss, tempStudent.sName, ';');
            // Use formatted input function to get the mark and convert it to an int
            iss >> tempStudent.mark;

            // So, now all parts are in the tempStudent. Add this to the result
            students.push_back(tempStudent);
        }

        // For debug purposes, we show all read data
        for (const Student& student : students)
            std::cout << student.fName << '\t' << student.sName << "\t Mark: " << student.mark << '\n';
    }
    else
        // File could not be opened. Show error message
        std::cerr << "\n\nError: 'file.txt' could not be opened\n";
}

对于更有经验的用户。 在 C++ 中,我们经常使用更面向 object 的方法。 我们存储数据方法,在 class 中对该数据进行操作。

C++ 允许我们覆盖提取>>和插入器<<运算符。 这些将成为 class 的一部分,并使 IO 更容易。

请参阅下面的更高级的解决方案:

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

class Student
{
public:
    std::string fName{};
    std::string sName{};
    int mark{};

    friend std::istream& operator >> (std::istream& is, Student& s) {
        if (std::string line{}; std::getline(is, line)) {
            std::istringstream iss{ line };
            std::getline(std::getline(iss, s.fName, ';'), s.sName) >> s.mark;
        }
        return is;
    }
    friend std::ostream& operator << (std::ostream& os, const Student& s) {
        return os << s.fName << '\t' << s.sName << "\t Mark: " << s.mark;
    }
};
class Students
{
public:
    std::vector<Student> data{};
    friend std::istream& operator >> (std::istream& is, Students& s) {
        s.data = { std::istream_iterator<Student>(is),{} };
        return is;
    }
    friend std::ostream& operator << (std::ostream& os, const Students& s) {
        for (const Student& d : s.data) os << d << '\n';
        return os;
    }
};

int main() {

    // Open file and check, if it could be opened
    if (std::ifstream sourceFileStream{ "file.txt" }; sourceFileStream) {

        // The file could be opened. Define a instance of Students
        Students students{};

        // Read all students
        sourceFileStream >> students;

        // Show all data
        std::cout << students;
    }
    else
        // File could not be opened. SHow error message
        std::cerr << "\n\nError: 'file.txt' could not be opened\n";
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM