上机六输入输出流程序设计
一、上机目的
1.了解 C++流类库结构。
2.掌握流类库中常用的类及其成员函数的使用方法。
3.了解常用控制符的使用,掌握 C++格式输入输出方法。
4.熟练掌握文件操作方法和文件流的输入输出。
二、上机内容
1.测试本章例题。
2.设计一个学生类,将 N 个学生对象的基本信息(姓名、身高、年龄)以二进制流的形式写入文件中,并将写入的文件信息在屏幕上进行随机显示
测试例题
[例 9.9] 随机访问文件。要求:
(1)设计一个包括姓名、学号和成绩的学生结构体。
(2)先把 3 个学生数据写入文件 bbb.dat,再从文件中读出第 2 个学生的数
据显示在屏幕上。
上机步骤:
(1)新建复数类模板头文件。选择菜单“File”——“New”,打开新建对话框,
如图 5-1 所示。选择“Files”标签中的“C/C++ Header File”,设置存储路径为
“D:\mywork\work6”,文件名称为“Student”。默认选中“Add to project”,如图 6-4
所示。
(2)单击“OK”按钮,打开 Student.h 文件,编辑代码如下:
//Student.h
struct Student{
char name[20];
long number;
int score;
};
(3)在主文件中 work6.cpp 中编辑测试代码:
#include "Student.h"
#include <fstream.h>
int main(int argc, char* argv[])
{
Student stu[3] = {
{
"Zhang", 111, 100}, {
"Li", 222, 90}, {
"Wang", 333, 80}},
stu2;
char filename[] = "bbb.data";
int n=3, i;
fstream datafile(filename, ios::in|ios::out|ios::binary);
for(i=0; i<3; i++)
datafile.write((char*)&stu[i], sizeof(struct Student));
datafile.seekg(1*sizeof(struct Student), ios::beg);
datafile.read((char*)&stu2, sizeof(struct Student));
datafile.close();
64
cout<<"Name: "<<stu2.name<<endl;
cout<<"Number: "<<stu2.number<<endl;
cout<<"score: "<<stu2.score<<endl;
return 0;
}
(4)在工具栏中单击“Build”命令图标 ,生成 work6.exe。
(5)在工具栏中单击“Excute”命令图标 ,运行 work6.exe,
- 上机实践
设计一个学生类,将 N 个学生对象的基本信息(姓名、身高、年龄)以二进制流的形式写入文件中,并将写入的文件信息在屏幕上进行随机显示。
上机步骤:
(1)新建复数类模板头文件。选择菜单“File”——“New”,打开新建对话框,如图 6-6 所示。选择“Files””标签中的“C/C++ Header File”,设置存储路径为“D:\mywork\work6”,文件名称“Student2”。默认选中“Add to project”,如图 6-6所示。
图 6-6 新建学生类头文件
(2)单击“OK”按钮,打开 Student2.h 文件,编辑代码如下:
//Student2.h
#include <string.h>
class Student{
public:
char name[20];
float height;
int age;
Student(char *n=" ", float h=1.6, int a=20) : height(h), age(a)
{
strcpy(name, n);
}
};
(3)在主文件中 work6.cpp 中编辑测试代码:
#include "stdafx.h"
#include "Student2.h"
#include <fstream.h>
int main(int argc, char* argv[])
{
int n;
cout<<"please input the number of student: ";
cin>>n;
66
Student *ps, stu;
ps = new Student[n];
char name[20];
float height;
int age;
for(int i=0; i<n; i++)
{
cout<<endl<<"Name: "; cin>>name;
cout<<"Height: "; cin>>height;
cout<<"Age: "; cin>>age;
*(ps+i) = Student(name, height, age);
}
char filename[] = "info.data";
fstream datafile(filename, ios::in|ios::out|ios::binary);
for(i=0; i<n; i++)
datafile.write((char*)(ps+i), sizeof(struct Student));
int num;
cout<<"Please input the number to print: ";
cin>>num;
while(num)
{
datafile.seekg((num-1)*sizeof(struct Student), ios::beg);
datafile.read((char*)&stu, sizeof(struct Student));
cout<<"Name: "<<stu.name<<endl;
cout<<"Height: "<<stu.height<<endl;
cout<<"Age: "<<stu.age<<endl;
cout<<"Please input the number to print: ";
cin>>num;
}
datafile.close();
return 0;
}
(4)在工具栏中单击“Build”命令图标 ,生成 work6.exe。
(5)在工具栏中单击“Excute”命令图标 ,运行 work6.exe
思考题
1.在 C++中通过控制文件指针的移动实现文件的随机访问,一般文本文件难准确定位,所以随机访问多用于二进制文件,请测试。C++实现文件的随机访问需要考虑哪几个因素?
在 C++ 中实现文件的随机访问需要考虑以下几个因素:
-
打开文件时,需要指定正确的文件访问模式和打开方式。对于二进制文件,应该使用“二进制”模式来进行读写操作,以避免对数据的意外改变。
-
文件指针位置的移动。通过调用 fseek 函数,可以将文件指针移动到所需位置,从而实现随机访问。在移动指针时,需要注意偏移量的单位及正负方向,以确保文件指针移动到正确的位置。
-
读取或写入数据的大小和格式。对于二进制文件,由于数据类型的大小和格式可能不同,因此需要根据具体情况决定读取或写入的数据大小和格式。
-
关闭文件时,需要确保所有的文件指针都正确地指向了文件末尾,以避免数据的丢失和损坏。
下面是一个简单的示例,演示如何在C++中随机访问一个二进制文件:
#include <iostream>
#include <fstream>
using namespace std;
int main() {
// 打开二进制文件
fstream file("test.bin", ios::out | ios::binary);
// 写入数据
int num1 = 12345;
float num2 = 3.1415926;
file.write(reinterpret_cast<char*>(&num1), sizeof(num1));
file.write(reinterpret_cast<char*>(&num2), sizeof(num2));
// 将文件指针移动到开头
file.seekg(0);
// 读取数据
int num3;
float num4;
file.read(reinterpret_cast<char*>(&num3), sizeof(num3));
file.read(reinterpret_cast<char*>(&num4), sizeof(num4));
// 输出数据
cout << "num1 = " << num3 << endl;
cout << "num2 = " << num4 << endl;
// 关闭文件
file.close();
return 0;
}
在上面的示例中,我们首先打开了一个名为“test.bin”的二进制文件,并向其中写入了一个整型数和一个浮点数。接着,通过调用 seekg 函数将文件指针移动到文件开头处,然后读取了这两个数据并输出。最后关闭了文件。
2.测试 seekp 函数和 seekg 函数实现文件指针重定位的区别?
在 C++ 中,文件指针有两种类型:读取指针和写入指针。为了方便操作,C++ 标准库分别提供了 seekg 和 seekp 函数来实现对这两种指针位置的重定位。
seekg 函数是用于改变当前文件读指针位置的函数,它可以让文件读指针在文件中任意一个位置定位,从而可以实现读取数据时的随机访问。而 seekp 函数则是用于改变当前文件写指针位置的函数,它可以让文件写指针在文件中任意一个位置定位,从而可以实现插入和修改数据时的随机访问。
下面是一个简单的示例,演示如何使用 seekg 和 seekp 函数实现文件指针的重定位:
#include <iostream>
#include <fstream>
using namespace std;
int main() {
// 打开文件
fstream file("test.txt", ios::out | ios::in);
// 写入数据
file << "0123456789";
// 重定位读指针(从开头开始向右移动3个字符)
file.seekg(3, ios::beg);
// 读取一个字符
char ch;
file.get(ch);
cout << ch << endl; // 输出3
// 重定位写指针(从当前位置开始向右移动2个字符)
file.seekp(2, ios::cur);
// 插入一个字符
file.put('A');
// 重定位读指针(从开头开始向右移动2个字符)
file.seekg(2, ios::beg);
// 读取一个字符
file.get(ch);
cout << ch << endl; // 输出0
// 关闭文件
file.close();
return 0;
}
在上面的示例中,我们首先打开了一个名为“test.txt”的文件,并向其中写入了一串数字字符串。接着,通过调用 seekg 函数将文件读指针移动到该字符串的第四个字符位置处,然后读取了这个字符并输出。接下来,我们通过调用 seekp 函数将文件写指针移动到当前读指针的后两个字符位置处,然后向文件中插入了一个大写字母“A”。最后,我们再次通过调用 seekg 函数将文件读指针移动到该字符串的第三个字符位置处,然后再次读取了这个字符并输出。
可以看出,通过使用 seekg 和 seekp 函数,我们可以灵活地控制文件指针的位置,从而实现了对文件数据的灵活访问和修改。需要注意的是,两个函数的偏移量参数的计算方式以及参数的含义略有不同,请根据具体情况选择合适的参数类型和参数值。
3.补充完善[上机实践]题目内容,对 N 个学生信息,根据用户需求(按照身高、年龄)对学生信息进行排序后再显示。