基于函数库的文件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; }