【问题标题】:Can't read file and store in data members of struct无法读取文件并存储在结构的数据成员中
【发布时间】:2016-01-18 00:29:56
【问题描述】:

这是一个分配,所以我遵循所需结构布局以及重载的分配准则。试图让我的程序读取每一行并将每一行分配给变量。

文本文件如下所示:

John 

S

Maggey

G

我的代码如下:

#include "iostream"
#include "fstream"
namespace
{
    char buffer[1024];
    int allocated = 0;
}

//====================================================================
struct student
{
    char *firstname;
    char lastname;
    int studentId;
    int occupied;

    student() : lastname(0), studentId(0), occupied(0)
    {
        firstname = new char[64];
        for (int i = 0; i < 64; ++i)
            firstname[i] = 0;
    }

    student(int s)
    {
        std::cout << "constructor" << std::endl;
        std::cout << "Allocated: " << allocated << std::endl;
        int currentLoc = allocated;
        allocated += s;
        firstname = new (&buffer[currentLoc]) char[s];
        for (int i = 0; i < 64; ++i)
            firstname[i] = 0;
    }

    void *operator new(size_t s)
    {
        std::cout << "Operator new allocated: " << allocated << std::endl;
        int currentLoc = allocated;
        allocated += s;
        return &buffer[currentLoc];
    }

    void student::operator delete(void *ptr)
    {
        std::cout << "Delete called " << std::endl;
        std::free(ptr);
    }

    student::~student()
    {
    }
};

//====================================================================
int main(int argc, char** argv)
{
    student *studentLoader = new student[25];

    std::fstream fin;
    fin.open("students.txt");
    char ln;
    for (int i = 0; i < 25; ++i)
    {
        fin.getline(studentLoader[i].firstname, 99);
        fin.getline(ln, 64);
        studentLoader[i].lastname = ln;
        studentLoader[i].studentId = (rand() % (9999 - 999)) + 999;
        studentLoader[i].occupied = 1;
        if ((i % 10) == 0)
        {
            std::cout << "First name: " << studentLoader[i].firstname << " Last initial: " << studentLoader[i].lastname << " ID: " << studentLoader[i].studentId << std::endl;
            delete[] studentLoader;
        }
    }
    fin.close();

    return 0;
}

我也尝试过:

    std::fstream fin;
    fin.open("students.txt");
    char ln;
    for (int i = 0; i < 25; ++i)
    {
        fin.getline(studentLoader[i].firstname, 99);
        fin.getline(studentLoader[i].lastname, 99);
        studentLoader[i].lastname = ln;
        studentLoader[i].studentId = (rand() % (9999 - 999)) + 999;
        studentLoader[i].occupied = 1;
        if ((i % 10) == 0)
        {
            std::cout << "First name: " << studentLoader[i].firstname << " Last initial: " << studentLoader[i].lastname << " ID: " << studentLoader[i].studentId << std::endl;
            delete[] studentLoader;
        }
    }
    fin.close();

    return 0;
}

但第二次尝试 getline 时会收到错误。

尝试时

fin >> studentLoader[i].firstname;

不会在变量中插入任何内容。

【问题讨论】:

  • 请使用std::string 而不是char*。也请不要newdelete
  • 您应该simplify your program 并删除任何不必要的代码(如newdelete 重载运算符)。
  • 这是一个任务,所以我遵循要求。我们需要重载这些运算符并使用 char*。
  • 你可以先明智地缩进你的代码,这样它实际上是可读的。
  • 进行了编辑以使其看起来更好,添加了关于为什么我使用 char* 并重载 new 和 delete 运算符的说明。

标签: c++ input struct fstream


【解决方案1】:

如果这不是一个拼写错误,并且您真的想为 lastname 使用单个字符,您也应该将其作为单个字符来阅读: fin &gt;&gt; studentLoader[i].lastname &gt;&gt; std::ws

还可以考虑阅读documentation 以了解您正在使用的函数和类。这通常是一个好习惯,可以让你避免很多失败。

【讨论】:

    【解决方案2】:

    通过将firstnamelastname 的类型更改为std::string 对您的struct student 稍作修改,您就不必动态分配/解除分配内存,您将代码减少一半。

    例如,您可以将其定义为:

    struct student {
    
        // constructor
        student (std::stirng fn, std::stirng ln, int ID, int oc) 
           :  firstname(fn), lastname(ln), studentID(ID), occupied(oc) { }
    
        // data members
        std::string firstname;
        std::string lastname;  
        int studentID;
        int occupied;
    }; 
    

    然后要从文件中读取并存储在struct student,您可以使用std::vector,如下所示:

    #include <iostream>
    #include <string>
    #include <vector>
    #include <sstream> 
    
    int main () {
        // stores all elements created from the reading of the file 
        std::vector<student> class_of_students;
    
        // attach an input stream
        std::ifstream fin("students.txt");
        // check if file successfully opened 
        if (!fin) std::cerr << "Can't open input file!\n";
    
        // line of text
        std::string line;
    
        // read file line by line
        while (getline(fin, line)) {
             // stream to extract data from a line
             std::stringstream ss(line);
    
             // input variables
             std::string first_name;
             std::string last_name;
             int ID;
             int occupied;
    
             // example that assumes line format: "f_name l_name ID occ"
             while (ss >> first_name >> last_name >> ID >> occupied) {
    
                 // store one element of type student to the vector
                 class_of_students.emplace_back(student(first_name, last_name, ID, occupied));
             }
        }
    }
    

    更多关于std::stringstd::vector的使用。

    注意:

    此外,当您生成学生ID 时,您需要它不仅是随机的,而且是唯一的。

    【讨论】:

      猜你喜欢
      • 2021-12-08
      • 1970-01-01
      • 2015-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-05
      • 2017-06-25
      相关资源
      最近更新 更多