【C&C++】面向文件的输入输出——实例探讨

基于函数库的文件I/O(C)

【输出】从键盘输入一批学生的成绩信息并把它们以文本格式存入外部文件:scores.txt

学生的成绩信息包括学号、姓名、选课数和各门课的成绩,如001 张三 4 70 80 87 92,以输入学号'E'结尾

#include <cstdio>
using namespace std;
int main()
{
    FILE *fp=fopen("d:\\scores.txt","w");
    if (fp==NULL)
    {
        printf("文件打开失败!\n");
        return -1;
    }
    char id[11],name[9];
    int num_of_courses, score;
    printf("请输入学号、姓名、选课数及各门课成绩(以学号E结束):\n");
    scanf("%10s", id);
    while (id[0]!='E')
    {
        scanf("%8s",name);
        scanf("%d",&num_of_courses);
        fprintf(fp,"%s %s %d",id,name,num_of_courses);
        for (int i=0;i<num_of_courses;i++)
        {
            scanf("%d",&score);
            fprintf(fp," %d",score);
        }
        fputc('\n',fp);
        scanf("%10s",id);
    }
    fclose(fp);
    return 0;
}

【输入】从上面输出的文件scores.txt中读入数据,计算每个学生的平均成绩并输出到显示器

#include <cstdio>
using namespace std;
int main()
{
    FILE *fp=fopen("d:\\scores.txt","r");
    if (fp==NULL)
    {
        printf("文件打开失败!\n");
        return -1;
    }
    char id[11],name[9];
    int num_of_courses,score,total;
    fscanf(fp,"%10s",id);
    while (!feof(fp))
    {
        fscanf(fp,"%8s",name);
        fscanf(fp,"%d",&num_of_courses);
        total=0;
        for(int i=0;i<num_of_courses;i++)
        {
            fscanf(fp,"%d",&score);
            total+=score;
        }
        printf("%s,%s,%d\n",id,name,total/num_of_courses);
        fscanf(fp,"%10s",id);
    }
    fclose(fp);
    return 0;
}

注:若同时输入+输出,则输入方式可以改成"r+"(打开一个外部文件用于读/写操作,文件必须存在)或"w+"(打开一个外部文件用于读/写操作,如果文件不存在则首先创建一个空文件,否则首先清空已有文件中的内容)

基于类库的文件I/O(C++)

【输出】从键盘输入一批学生的成绩信息并把它们以文本格式存入外部文件:scores.txt

学生的成绩信息包括学号、姓名、选课数和各门课的成绩,如001 张三 4 70 80 87 92,以输入学号'E'结尾

#include <iostream>
#include <fstream>//库函数输入输出的头文件
#include <iomanip>
using namespace std;
const int MAX_NUM_OF_COURSES=30;
const int MAX_ID_LEN=10;
const int MAX_NAME_LEN=8;
class StudentScores
{
public:
    StudentScores() {initialized=false;}
    bool data_is_ok() const {return initialized;}
private:
    int scores[MAX_NUM_OF_COURSES],num_of_courses;
    char id[MAX_ID_LEN+1],name[MAX_NAME_LEN+1];
    bool initialized;
    //通过重载操作符 << 和 >> 实现对StudentScores类的数据的输入/输出操作
    friend istream &operator >> (istream &in, StudentScores &x);
    friend ostream &operator << (ostream &out, const StudentScores &x);
}
istream &operator >> (istream &in, StudentScores &x)
{
    if (&in==&cin)//从键盘输入时需要给出提示
        cout << "请输入学号、姓名、选课数及各门课成绩(以学号E结束):\n";
    in >> setw(11) >> x.id;
    if (in.eof() || x.id[0]=='E')
    {
        x.initialized=false;
        return in;
    }
    in >> setw(9) >> x.name;
    in >> x.num_of_courses;
    if (x.num_of_courses>MAX_NUM_OF_COURSES)
    {
        x.initialized=false;
        return in;
    }
}
ostream &operator << (ostream &out, const StudentScore &x)
{
    out << x.id << ' ' << x.name << ' ' << x.num_of_courses;
    for (int i=0;i<x.num_of_courses;i++)
        out << ' ' << x.scores[i];
    return out;
}
int main()
{
    ofstream out_file("d:\\scores.txt",ios::out);//创建并打开文件
    if (!out_file)//判断是否成功打开
    {
        cerr << "打开文件失败!\n";
        return -1;
    }
    StudentScores st;
    cin >> st;
    while (st.data_is_ok())
    {
        out_file << st << endl;//输出操作
        cin >> st;
    }
    out_file.close();//关闭文件
    return 0;
}

【输入】从上面输出的文件scores.txt中读入数据,计算每个学生的平均成绩并输出到显示器

#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;
const int MAX_NUM_OF_COURSES=30;
cosnt int MAX_ID_LEN=10;
const int MAX_NAME_LEN=8;
class StudentScores
{
public:
    StudentScores() {initialized=false;}
    bool data_is_ok() {return initialized;}
    const char *get_id() const {return id;}
    const char *get_name() const {return name;}
    int average_score() const
    {
        int total=0;
        for (int i=0;i<num_of_courses;i++)
            total+=scores[i];
            return total/num_of_courses;
    }
private:
    int scores[MAX_NUM_OF_COURSES],num_of_courses;
    char id[MAX_ID_LEN+1],name[MAX_NAME_LEN+1];
    bool initialized;
    friend istream &operator >> (istream &in, StudentScores &x);
    friend ostream &operator << (ostream &out, const StudentScores &x);
}
......//同上例,对操作符 >> 和 << 进行重载
int main()
{
    ifstream in_file("d:\\scores.txt",ios::in);//打开文件
    if (!in_file)//判断是否成功打开
    {
        cerr << "文件打开失败!\n";
        return -1;
    }
    cout << "学号,姓名,平均成绩:\n";
    StudentScores st;
    in_file >> st;//输入操作
    while (st.data_is_ok())
    {
        cout << st.get_id() << ',' << st.get_name << ',' << st.average_score() << endl;
        in_file >> st;//输入操作
    }
    in_flie.close();//关闭文件
    return 0;
}

注:若同时输入+输出,则采用下面的代码:

fstream io_file("d:\\scores.txt", ios::in|ios::out)

【随机存取】(1)从键盘读入一批学生的信息并把它们以二进制格式存入外部文件:student.dat

(2)根据学号在(1)中生成的数据文件(students.dat)中查找某个学生信息并修改该学生的专业

(1)学生信息包括学号、姓名、性别、出生日期、出生地和专业。在输入时,以输入学号"E"结束。

#include <cstdio>
using namespace std;
//先定义结构类型Student
enum Sex {MALE,FEMALE};
struct Date
{
    int year;
    int month;
    int day;
};
enum Major { MATHEMATICS,PHYSICS,CHEMISTRY,COMPUTER,GEOGRAPHY,ASTRONOMY,ENGLISH,CHINESE,PHILOSOPHY};
struct Student
{
    char id[11];
    char name[9];
    Sex sex;
    Date birth_date;
    char birth_place[40];
    Major major;
};
//文件的输出
int main()
{
    FILE *fp=fopen("d:\\students.dat","wb");//用二进制方式打开文件用于输出
    if (fp==NULL)
    {
        printf("打开文件失败!\n");
        return -1;
    }
    Student st;
    printf("请输入学号、姓名、性别、出生日期、出生地和专业(以学号E结束):\n");
    scanf("%10s",st.id);
    while (st.id[0]!='E')
    {
        ...... //读入姓名、性别、出生日期、出生地和专业至变量st中
        fwrite(&st,sizeof(st),1,fp);//以二进制格式输出变量st的值到文件
        scanf("%10s",st.id)
    }
    fclose(fp);//关闭文件
    return 0;
}

(2)随机存取——指定一个位置并获得相应的指针位置

对于以输入方式打开的文件,指定文件内部指针位置:
istream& istream::seekg(<位置>); //指定绝对位置
istream& istream::seekg(<偏移量>,<参照位置>); //指定相对位置
streampos istream::tellg(); //获得指针位置
​
对于输出文件,可用下面的操作来制定文件内部指针位置:
ostream& ostream::seekp(<位置>); //指定绝对位置
ostream& ostream::seekp(<偏移量>,<参照位置>); //指定相对位置
streampos ostream::tellp(); //获得指针位置
​
其中,<参照位置>可以是 ios::beg(文件头)、ios::cur(当前位置)和ios::end(文件尾)
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstring>
using namespace std;
...... //即Students结构类型的定义
class StudentsFile
{
public:
    StudentsFile(const char filename[])
        io_file.open(filename,ios::in|ios::out|ios::binary);
    ~StudentsFile()
        io_file.close();
    bool is_open() const {return io_file.is_open;}
    int find(char id[],Student& st) //查找学号为id的学生
    {
        int index=0;
        io_file.seekg(0);
        io_file.read((char*)&st,sizeof(st));//读入第一个学生的数据
        while (!io_file.eof())//循环查找学号为id的学生
        {
            if (strcmp(st.id,id)==0)
                return index;//返回找到的学生在文件中的位置
            index++;
            io_file.read((char*)&st,sizeof(st));//读入下一个学生的数据
        }
        return -1;//没找到返回-1
    }
    bool put_at(int index, Student& st)//更新文件中指定位置上的徐盛信息
    {
        io_file.seekp(index*sizeof(st));//文件位置指针定位
        if (io_file.fail())
            return false;
        io_file.write((char*)&st,sizeof(st));//写入数据
        return !io_file.fail();
    }
private:
    fstream io_file;//用于文件输入/输出的成员对象
}
int main()
{
    StudentsFile students_file("d:\\students.dat");
    if (!students_file.is_open())
    {
        cerr << "文件打开失败!";
        return -1;
    }
    char id[11];
    int major;
    cout << "请输入要查找学生的学号:";
    cin >> setw(11) >> id;
    cout << "请输入要改成的专业\n"
        << "(0:MATHEMATICS,1:PHYSICS,2:CHEMISTRY,3:COMPUTER,\n"
        << "4:GEOGRAPHY,5:ASTRONOMY,6:ENGLISH,7:CHINESE,8:PHILOSOPHY):";
    cin >> major;
    Student st;
    int i=students_file.find(id,st);
    if (i==-1)
    {
        cout << "\n没找到学号为" << id << "的学生。\n";
        return -1;
    }
    else
    {
        st.major=(Major)major;//修改找到的学生的专业
        students_file.put_at(i,st);
        cout << "\n学号为" << id << "的学生信息已更新。\n";
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值