c++为什么从文件读数据读到的是空的?

下面这一段代码没法从文件中读入信息,看了好久也没发现哪里有问题。


int list::load(list* head) {

    list* rear = head;
    list* p = new list;

    ifstream ofile("d:\\stu.txt");
    if (!ofile) {
        cout << "打开文件失败" << endl;
        return 1;
    }
    
    for (;(ofile >> p->stu.ID >> p->stu.Name >> p->stu.Sex >> p->stu.IDC >> p->stu.Age >> p->stu.BP >> p->stu.Yx >> p->stu.Zy >> p->stu.Bj >> p->stu.Xz);) {
        rear->next = p;
        rear = p;
        rear->next = NULL;
        student::M += 1;
        list* p = new list;
    }
    cout << "文件读入成功" << endl;
    ofile.close();
}

以下是完整代码


#include<iostream>
using namespace std;
#include<stdio.h> 
#include<stdlib.h>
#include<string.h>
#include<fstream>

class student {
public:
    char ID[15];  //学号
    char Name[15];//姓名
    char Sex[3];  //性别
    char IDC[10]; //身份证号
    int  Age;     //年龄
    char BP[15];  //籍贯
    char Yx[30];  //院系
    char Zy[30];  //专业
    char Bj[30];  //班级
    char Xz[5];   //学制
    static int M;
};
class list {
public:
    student stu;
    list* next;

    void Insert(list *);//添加学生信息
    void Delete(list *);//删除学生信息
    void Modify(list *);//修改学生信息
    void Search(list *);//查找学生信息
    void  xsxx (list *);//输出所有学生信息
    int Save(list *);   //保存学生信息到文件
    int load(list *);//从文件中加载学生信息
};

void list::Insert(list* head) {
    list* rear = head;

    list* p = new list;

        cout<<"请输入学生的学号:";
        cin>>p->stu.ID;
        cout<<"请输入学生的姓名:";
        cin>>p->stu.Name;
        cout<<"请输入学生的性别:";
        cin>>p->stu.Sex;
        cout<<"请输入学生的身份证号:";
        cin>>p->stu.IDC;
        cout<<"请输入学生的年龄:";
        cin>>p->stu.Age;
        cout<<"请输入学生的籍贯:";
        cin>>p->stu.BP;
        cout<<"请输入学生的院系:";
        cin>>p->stu.Yx;
        cout<<"请输入学生的专业:";
        cin>>p->stu.Zy;
        cout<<"请输入学生的班级:";
        cin>>p->stu.Bj;
        cout<<"请输入学生的学制:";
        cin>>p->stu.Xz;
        cout<<"\n";
        for (; rear->next != NULL; rear = rear->next);

        rear->next = p;
        rear = p;
        rear->next = NULL;
        student::M += 1;

    cout<<"\n";
    cout<<"学生信息添加完毕!\n";
    cout<<"\n";
}
void list::Delete(list* head) {

    char c[15]; int i;
    int x = 0;

    cout<<"请输入要删除学生的学号:";
    cin>>c;
    list* pre = head;
    list* p;
    for (i = 0; i < student::M; i++) {
        p = pre->next;

        if (strcmp(p->stu.ID, c) == 0) {
            pre->next = p->next;

            x = 1;
            break;
        }
        pre = pre->next;
    }
    if (x == 0) { cout<<"该学号不存在\n"; return; }

    student::M--;
    cout<<"该学生信息已删除\n";
}
void list::Modify(list* head) {

        int i, x = 0, item = 1;
        char a[15];
        cout<<"请输入要修改的学生学号:";
        cin>>a;

        list* p, * pre;
        pre = head;

        for (i = 0; i < student::M; i++) {
            p = pre->next;
            if (strcmp(p->stu.ID, a) == 0) {//判断学号是否存在

                x = 1;
                cout<<"存在该学生,请输入您要进行的操作:\n";

                while (1) {
                    cout<<"1.修改姓名 ";
                    cout<<"2.修改性别 ";
                    cout<<"3.修改身份证号 ";
                    cout<<"4.修改年龄 ";
                    cout<<"5.修改籍贯 ";
                    cout<<"6.修改学院 ";
                    cout<<"7.修改专业 ";
                    cout<<"8.修改班级 ";
                    cout<<"9.修改学制 ";
                    cout<<"0.退出修改 ";
                    cout<<"\n";
                    cout<<"请输入您的操作:";
                    cin>>item;

                    switch (item) {

                    case 0:break;
                    case 1:cout<<"请输入新的名字:";
                        cin>>p->stu.Name; break;
                    case 2:cout<<"请输入新的性别:";
                        cin>>p->stu.Sex; break;
                    case 3:cout<<"请输入新的身份证号:";
                        cin>>p->stu.IDC; break;
                    case 4:cout<<"请输入新的年龄:";
                        cin>>p->stu.Age; break;
                    case 5:cout<<"请输入新的籍贯:";
                        cin>>p->stu.BP; break;
                    case 6:cout<<"请输入新的院系:";
                        cin>>p->stu.Yx; break;
                    case 7:cout<<"请输入新的专业:";
                        cin>>p->stu.Zy; break;
                    case 8:cout<<"请输入新的班级:";
                        cin>>p->stu.Bj; break;
                    case 9:cout<<"请输入新的学制:";
                        cin>>p->stu.Xz; break;
                    }
                    if (item == 0) break;
                    cout<<"修改成功\n";
                }

            }
            if (item == 0) break;
            pre = pre->next;
        }
        if (x != 1) cout<<"未找到该学生\n";

}
void list::Search(list* head) {

    int i, x1 = 0;
    char b[15];

    cout<<"请输入要查找的学生学号:";
    cin>>b;
    list* p, * pre;
    pre = head;
    for (i = 0; i < student::M; i++) {

        p = pre->next;
        if (strcmp(p->stu.ID, b) == 0) {
            x1 = 1;
            printf("学号:%s  姓名:%s  性别:%s  身份证号:%s  年龄:%d  籍贯:%s  学院:%s  专业:%s  班级:%s  学制:%s\n", p->stu.ID, p->stu.Name, p->stu.Sex, p->stu.IDC, p->stu.Age, p->stu.BP, p->stu.Yx, p->stu.Zy, p->stu.Bj, p->stu.Xz);
            cout<<"\n";
        }
        pre = pre->next;

    }if (x1 != 1) cout<<"未找到该学生\n";
}
void list::xsxx(list* head) {

    int i;

    cout<<"********************学生信息*********************\n";
    cout<<"\n";
    cout<<"学生总人数:%d\n", student::M;
    cout<<"学号  姓名  性别  身份证号  年龄  籍贯  院系  专业   班级   学制\n";
    list* pre;
    pre = head;
    for (i = 0; i < student::M; i++){
        pre = pre->next;
        printf(" %s    %s    %s   %s   %d   %s  %s  %s  %s  %s\n", pre->stu.ID, pre->stu.Name, pre->stu.Sex, pre->stu.IDC, pre->stu.Age, pre->stu.BP, pre->stu.Yx, pre->stu.Zy, pre->stu.Bj, pre->stu.Xz);
    }
}
int list::Save(list* head) {

    ofstream file("d:\\stu.txt");
    if (!file) {
        cout << "文件打开失败!" << endl;
        return 1;
    }
    list* pre;
    pre = head;
    
    for (int i = 0; i < student::M; i++) {
        pre = pre->next;
        file << pre->stu.ID << " " << pre->stu.Name << "" << pre->stu.Sex << " " << pre->stu.IDC << " " << pre->stu.Age << " " << pre->stu.BP << " " << pre->stu.Yx << " " << pre->stu.Zy << " " << pre->stu.Bj << " " << pre->stu.Xz << "\n";
    }
    cout << "文件保存成功" << endl;
    file.close();
}
int list::load(list* head) {

    list* rear = head;
    list* p = new list;

    ifstream ofile("d:\\stu.txt");
    if (!ofile) {
        cout << "打开文件失败" << endl;
        return 1;
    }
    
    for (;(ofile >> p->stu.ID >> p->stu.Name >> p->stu.Sex >> p->stu.IDC >> p->stu.Age >> p->stu.BP >> p->stu.Yx >> p->stu.Zy >> p->stu.Bj >> p->stu.Xz);) {
        rear->next = p;
        rear = p;
        rear->next = NULL;
        student::M += 1;
        list* p = new list;
    }
    cout << "文件读入成功" << endl;
    ofile.close();
}

void menu(list& p, list* head);//操作菜单

int student::M = 0;

int main(void) {
    list* head = new list;
    head->next = NULL;
    list s;
    char mm[10] = "123456";
    char m[10];
    int k = 0;
    while (1) {
        cout<<"请输入密码:";
        scanf_s("%s", m, 10);

        if (strcmp(m, mm) == 0) {
            k = 1;
            while (1) {

                menu(s,head);

                system("pause");

            }
        }
        else cout<<"密码错误\n";

        if (k == 1) break;
    }
    return 0;
}

void menu(list &s,list *head) {

    system("cls");//清空不必要的显示内容

    int num;

    cout<<"1.添加学生信息\n";
    cout<<"2.删除学生信息\n";
    cout<<"3.修改学生信息\n";
    cout<<"4.查找学生信息\n";
    cout<<"5.输出所有学生信息\n";
    cout<<"6.保存学生信息到文件\n";
    cout<<"7.从文件中读取学生信息\n";
    cout<<"8.退出系统\n";
    cout<<"--------------------------------------------------------------------------------------------------\n";
    cout<<"--------------------------------------------------------------------------------------------------\n";
    cout<<"请选择您的操作:";
    cin>>num;

    switch (num) {

    case 1:
        s.Insert(head);
        break;
    case 2:
        s.Delete(head);
        break;
    case 3:
        s.Modify(head);
        break;
    case 4:
        s.Search(head);
        break;
    case 5:
        s.xsxx(head);
        break;
    case 6:
        s.Save(head);
        break;
    case 7:
        s.load(head);
        break;
    case 8:
        cout<<"\n";
        cout<<"***********程序已退出***********";
        exit(0);
    default:cout<<"请输入正确的数字\n";
        cout<<"\n";
        break;
    }
}

 
int list::load(list* head) {
 
    list* rear = head;
    list* p = new list;
 
    ifstream ofile("d:\\stu.txt");
    if (!ofile) {
        cout << "打开文件失败" << endl;
        return 1;
    }
    
    for (;(ofile >> p->stu.ID >> p->stu.Name >> p->stu.Sex >> p->stu.IDC >> p->stu.Age >> p->stu.BP >> p->stu.Yx >> p->stu.Zy >> p->stu.Bj >> p->stu.Xz);) {
        rear->next = p;
        rear = p;
        rear->next = NULL;
        student::M += 1;
         p = new list;
    }
    cout << "文件读入成功" << endl;
    ofile.close();
}

乍看起来c++的cin、cout、ifstream、ofstream、istringstream、ostringstream在输入、输出上比c的scanf、printf、fscanf、fprintf、fread、fwrite、sscanf、sprintf简单,不用格式控制符!
但是不用格式控制符,输入输出恰好是你期望的格式的时候好说;等到输入输出不是你期望的格式的时候,你就会觉得还是用格式控制符更方便、更靠谱。
摒弃cin、cout、ifstream、ofstream、istringstream、ostringstream!
使用scanf、printf、fscanf、fprintf、fread、fwrite、sscanf、sprintf。

输入尽量一个一个输入,不要把一大堆代码写到同一行,很难调试
断点跟,或者打print,看从哪一个开始出现错乱了,有针对性的改,不要全靠猜

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 你可以参考下这个问题的回答, 看看是否对你有帮助, 链接: https://ask.csdn.net/questions/7490826
  • 这篇博客也不错, 你可以看下C++从键盘上输入一个整数作为半径,求以它为半径的圆的面积和周长。
  • 除此之外, 这篇博客: C++读文件操作中的        文本输入,它是基于控制台输入的。控制台输入涉及多个方面,下面首先总结这些方面。 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:
    • 必须包含头文件iostream。
    • 头文件iostream定义了一个用处理输入的istream类。
    • 头文件iostream声明了一个名为cin的istream变量(对象)。
    • 必须指明名称空间std;例如,为引用元素cin,必须使用编译指令using或前缀std::。
    • 可以结合使用cin和运算符>>来读取各种类型的数据。
    • 可以使用cin和get( )方法来读取一个字符,使用cin和getline( )来读取一行字符。
    • 可以结合使用cin和eof( )、fail( )方法来判断输入是否成功。
    • 对象cin本身被用作测试条件时,如果最后一个读取操作成功,它将被转换为布尔值true,否则被转换为false。
  • 您还可以看一下 夏曹俊老师的C++ 设计模式原理与实战大全-架构师需备课程课程中的 构建者模式的实用工程技术——代码的坏味道:算法与对象构建的隔离小节, 巩固相关知识点
  • 以下回答来自chatgpt:

    解决方案:

    从文件中读取数据可以使用C++标准库中的fstream库或者cstdio库中的fopen、fread等函数,在这里介绍使用fstream库的方法。代码中文件路径需要根据实际情况进行修改。

    #include <fstream>
    using namespace std;
    
    int main() {
        ifstream fin("data.txt");  //打开文件
        if (!fin.is_open()) {  //判断是否打开成功
            cout << "文件打开失败!" << endl;
            return 0;
        }
        int num;
        while (fin >> num) {  //从文件中读取数据
            cout << num << " ";
        }
        fin.close();  //关闭文件
        return 0;
    }
    

    上面的代码中,使用了ifstream类打开文件,is_open()函数用于判断文件是否打开成功,>>操作符可用于从文件中读取数据(具体根据文件中数据的数据类型而定),最后使用close()函数关闭文件。

    如果文件中的数据类型为字符串,可以使用getline()函数从文件中一行一行地读取字符串。代码如下:

    #include <fstream>
    using namespace std;
    
    int main() {
        ifstream fin("data.txt");  //打开文件
        if (!fin.is_open()) {  //判断是否打开成功
            cout << "文件打开失败!" << endl;
            return 0;
        }
        string str;
        while (getline(fin, str)) {  //从文件中读取字符串
            cout << str << endl;
        }
        fin.close();  //关闭文件
        return 0;
    }
    

    一般来说,如果无法从文件中读取到数据,需要确认以下几点:

    1. 文件路径是否正确;
    2. 文件是否存在;
    3. 是否以正确的方式打开文件,例如读模式、写模式等。

    如果以上几点没有问题,还是无法从文件中读取到数据,可以考虑是否是数据类型问题,需要确认从文件中读取的数据类型与代码中的数据类型是否一致。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^