当前课程知识点:C++语言程序设计进阶 > 第十一章 流类库与输入/输出 > 输入流 > 输入流应用举例
//11_7.cpp #include <iostream> using namespace std; int main() { char ch; while ((ch = cin.get()) != EOF) cout.put(ch); return 0; }
//11_8.cpp #include <iostream> #include <string> using namespace std; int main() { string line; cout << "Type a line terminated by 't' " << endl; getline(cin, line, 't'); cout << line << endl; return 0; }
//11_9.cpp #include <iostream> #include <fstream> #include <cstring> using namespace std; struct SalaryInfo { unsigned id; double salary; }; int main() { SalaryInfo employee1 = { 600001, 8000 }; ofstream os("payroll", ios_base::out | ios_base::binary); os.write(reinterpret_cast<char *>(&employee1), sizeof(employee1)); os.close(); ifstream is("payroll", ios_base::in | ios_base::binary); if (is) { SalaryInfo employee2; is.read(reinterpret_cast<char *>(&employee2), sizeof(employee2)); cout << employee2.id << " " << employee2.salary << endl; } else { cout << "ERROR: Cannot open file 'payroll'." << endl; } is.close(); return 0; }
//11_10.cpp, 头部分省略 int main() { int values[] = { 3, 7, 0, 5, 4 }; ofstream os("integers", ios_base::out | ios_base::binary); os.write(reinterpret_cast<char *>(values), sizeof(values)); os.close(); ifstream is("integers", ios_base::in | ios_base::binary); if (is) { is.seekg(3 * sizeof(int)); int v; is.read(reinterpret_cast<char *>(&v), sizeof(int)); cout << "The 4th integer in the file 'integers' is " << v << endl; } else { cout << "ERROR: Cannot open file 'integers'." << endl; } return 0; }
//11_11.cpp, 头部分省略 int main() { ifstream file("integers", ios_base::in | ios_base::binary); if (file) { while (file) {//读到文件尾file为0 streampos here = file.tellg(); int v; file.read(reinterpret_cast<char *>(&v), sizeof(int)); if (file && v == 0) cout << "Position " << here << " is 0" << endl; } } else { cout << "ERROR: Cannot open file 'integers'." << endl; } file.close(); return 0; }
大家好
欢迎继续学习C++语言程序设计
这一节我们通过例子
来观察一下
如何应用输入流
首先我们来看一个
get函数的应用例子
这里我们在这个while循环中
每次从键盘读取一个字符
然后将这个字符
送到显示器上显示
大家看我们是通过cin
这个标准输入流对象
调用get函数
从键盘读取一个字符的
get函数的返回值呢
就是读到的这个字符
我们将它赋值给字符新变量ch
然后在while循环体中
调用put函数
通过cout调用put函数
将这一个字符送到显示器上
那怎么控制
这个while循环的结束呢
我们用读到的这个字符
去跟文件结束标记进行比较
看是不是到文件结束了
到文件结束了就停止
这个while循环
那么作为键盘
这个标准设备
它代表的文件
它的文件结束符是什么呢
在不同的操作系统中
对这个文件结束符的规定
也是不同的
如果你使用的是
windows系统的话
这时候你在键盘上
同时按下ctrl和z
就说明当前这个文本文件结束了
也就是说
你这一次键盘输入结束了
那么while循环就停止了
接下来的例子中呢
我们为输入流指定一个终止符
大家看一下
它的效果是什么
如果我们希望从键盘
输入一个字符串
那这个时候
该怎么做呢
其实从其他的文本文件中
输入字符串
也是一样的
因为键盘也是一个文本文件
这时候大家是不是想到
可以用cin提取运算符
去从键盘提取字符串
但是使用cin
和提取运算符的时候
大家是不是知道
它是以空格作为分界符的
也就是说
它好象阅读
文本文件中的单词一样
它具有词处理功能
一个单词一个单词地提取
遇到空白符就跳过去了
空白符
作为它提取字符串的分隔符
如果我们希望
从键盘输入一串字符串
或者从文本文件中
读取一串这个字符串
其中包括空格
那该怎么办呢
这个时候我们可以用
getline这个函数
getline这个函数它的第一个参数需要是
一个文本文件的输入流对象
这里我们还是以cin为例
从键盘来提取
第二个呢
是一个string对象
就是你输入的字符串
将放到哪儿去
第三个参数是可选的
作为分隔符
我们可以指定一个字符
作为分隔符
如果不指定的话呢
默认的情况下
会以换行为分隔符
这样我们用这样的方式
从键盘就可以读入一行
带空格的字符串
直到遇到我们指定的分隔符
就停止
下面这个例题呢
以二进制的方式从文件中
读取一个记录
放到结构体对象中
这个例题呢
演示一下以二进制方式
将信息写入到文件中
然后同样以二进制方式
再把以前写入的信息
再读回到程序中来
为此呢
我们定义了一个结构体
SalaryInfo
我们希望将一个结构体对象
以二进制的方式写到文件中
怎么写呢
大家看这里定义好
并且初始化好一个结构体对象
employee1
然后构造一个文件输出流对象
ofstream对象 os
把它与当前文件夹下的payroll
这个名字的文件结合起来
然后指定是输出的方式
是二进制的方式
指定这样的打开模式
打开成功以后呢
就调用write函数
将从employee1的起始地址
开始的 全部内容
也就是sizeof(employee1)
这么多个字节
全部一次性地写到磁盘文件中去
同样呢
跟前面例题里面一样
第一个是employee1的首地址
但是我们在write函数中
需要一个字符指针
所以将它临时转换成
一个字符指针
以满足函数的需要
好 写完了这一个对象以后
就关闭文件
接下来我们再次打开文件
这一次呢
用文件输入流对象
去打开这个文件payroll
打开的模式是输入模式
同时也是二进制模式
这个时候如果打开成功了
那我们就定义一个
SalaryInfo的对象employee2
然后调用这个ifstream对象is
它的read函数
从这个文件中读取数据
从它的当前位置开始
一打开当然
当前的读位置就是文件开头了
从当前位置开始
读多少个字节呢
连续读取sizeof(employee2)
这么多个字节
然后把它放在
我们刚才定义的对象employee2
它的首地址开始的位置
这个地址也需要转换成字符指针
然后我们再通过
cout输出验证一下
通过验证呢
我们可以看到
当初写进去的东西
都如实地读出来了
这就是从二进制文件中
读取一个以前写进去的对象
这个例题呢
用seekg函数去移动
文件位置指针
这样我们就可以
按照指定的字节位置
去读取信息了
在这个程序中呢
我们将一组五个整数
整体地写到
二进制的磁盘文件中去
然后呢
再从文件中去读取
它的第四个整数出来
也就是如果一开始
序号从0开始数的话
那么就是序号为3的这个数据
也就是将这个5
从磁盘文件中读取出来
首先我们看怎么写进去
还是构造一个
二进制的文件输出流对象
ofstream对象
这个os跟文件名integers
结合起来
也就是说
将来要写到文件名integers里面去
打开方式是输出是二进制的
然后接下来我们就开始写
从文件开始位置
也就是当前位置开始写
写多少个字节呢
sizeof(values)
就把整个数组的内容都写进去了
sizeof(values)
它会计算出整个数组
所占的字节数
然后这个values呢
正好是数组名
也就是数组的首地址
就是从这里开始取数据
取sizeof(values)这么多个字节
写到磁盘上的二进制文件
integers里面去
这个地方要转换成
指向字符的指针
写完了以后
要用close关闭
然后再另外打开这个文件
打开的时候呢
就将这个文件
与ifstream的对象 is关联起来
打开的模式是输入是二进制
那我们打开以后呢
并不希望顺序从第一个元素
开始读取
我们希望一下直接就把5
这个元素读出来
这个元素呢
它前面有三个元素
也就是说它的序号是3
从0开始
这时候我们怎么能够跳跃
前面的元素
直接从磁盘上
将这个5读出来呢
我们要用这个
ifstream对象的seekg函数
这个seekg函数呢
在这里可以指定
移动读指针的字节数
那就是3倍的sizeof(int)
因为前面要越过三个int数据
它移动的字节数
就是3乘以sizeof这么多个字节数
然后移动定位好了读指针以后
通过read函数
去读一个整数出来
所以这个地方是sizeof(int)
读一个整数出来
读出来以后放到哪儿呢
放到这个整数变量里面
所以这里我们给它
一个int变量的地址
同样需要把它转换成字符地址
这就是用seekg这个函数
去移动文件读指针的位置
然后从指定的字节读取数据
这个时候特别注意
移动的字节数要一定计算准确
不然的话
读出来的数据就没有意义了
接下来我们看
我们在一个文件中去找
它有没有0这个元素
如果找到了的话呢
返回这个0在文件中的位置
也就是
它在文件中的第几个字节的位置
这个程序就从
前面例题生成的那个
包含一组整数的那个
integers文件中读取整数
读取到0
就显示一下
0元素所在的位置序号
好 首先我们还是打开文件
构造ifstream对象file
将它用integers这个文件相关联
打开模式是输入是二进制
然后如果打开成功的话呢
在if分支中呢
就用一个while循环
来不停地从文件里面读
什么时候如果遇到文件尾了
这个file对象
它本身就为0了
只要没有遇到文件尾
我们就一直往下读
每一次读取下一个数据之前呢
都先调用tellg
去取得当前读指针的位置
也就是接下来该读哪个字节了
去取得当前读指针的位置
然后接下来调用read函数来读
每次读取一个整数
所以这个每次读取的字节数
是sizeof(int)这么多个字节
读出来的数据
放到int变量v里面
所以把v的地址放这儿
转换成字符指针
然后接下来呢我们看
如果文件没有结束
并且v等于0的话
那么就显示当前这个0
所在的位置
这个here是当时我们用
tellg返回当前读指针的位置
就这样的话呢
我们通过这个while循环
就将0值
这个值所在的位置
就反馈回来了
都完成以后呢
要注意关闭文件
-导学
--导学
-继承的基本概念和语法
-第七章 继承与派生--继承的基本概念和语法习题
-继承方式
-第七章 继承与派生--继承方式
-基类与派生类类型转换
-第七章 继承与派生--基类与派生类类型转换
-派生类的构造和析构
--派生类的构造函数
--派生类的析构函数
--第七章 继承与派生--派生类的构造和析构
-派生类成员的标识与访问
--虚基类
-第七章 继承与派生--派生类成员的标识与访问
-小结
--小结
-综合实例
--第七章综合实例
-实验七
--实验七
-导学
--导学
-第八章 多态性--导学
-运算符重载
--运算符重载的规则
-第八章 多态性--运算符重载
-虚函数
--虚函数
--虚析构函数
--虚表与动态绑定
-第八章 多态性--虚函数
-抽象类
--抽象类
--第八章 多态性--抽象类
-override与final
-第八章 多态性--override与final
-小结
--第八章小结
-综合实例
--第八章综合实例
-实验八
--实验八
- 第八章讲义
-导学
--导学
-模板
--函数模板
--类模板
-第九章 模板与群体数据--模板
-线性群体
--线性群体的概念
-第九章 模板与群体数据--线性群体
-数组
--数组类模板
-链表
--链表类模板
-第九章 模板与群体数据--链表
-栈
--栈类模板
--栈类模板课后习题
--例9-9 栈的应用课后习题
-队列
--队列类模板
-第九章 模板与群体数据--队列
-排序
--排序概述
--插入排序
--选择排序
--交换排序
-第九章 模板与群体数据--排序
-查找
--查找
--查找课后习题
-小结
--小结
-综合实例
--综合实例
-实验九
--实验九
- 第九章讲义
-导学
--导学
-泛型程序设计及STL的结构
--STL简介
-第十章 泛型程序设计与C++标准模板库--泛型程序设计及STL的结构
-迭代器
--迭代器
-第十章 泛型程序设计与C++标准模板库--迭代器
-容器的基本功能与分类
-第十章 泛型程序设计与C++标准模板库--容器的基本功能与分类
-顺序容器
--顺序容器的特征
--第十章 泛型程序设计与C++标准模板库--顺序容器
-关联容器
--集合
--映射
-第十章 泛型程序设计与C++标准模板库--关联容器
-函数对象
--函数对象
--函数适配器
-算法
--算法
-小结
--第十章小结
-综合实例
--综合实例
-实验十
--实验十
- 第十章讲义
-导学
--导学
-I/O流的概念及流类库结构
-第十一章 流类库与输入/输出--I/O流的概念及流类库结构
-输出流
--输出流概述
--向文本文件输出
--向二进制文件输出
--向字符串输出
-第十一章 流类库与输入/输出--输出流
-输入流
--输入流概述
--输入流应用举例
--从字符串输入
-第十一章 流类库与输入/输出--输入流
-输入/输出流
--输入/输出流
-第十一章 流类库与输入/输出--输入/输出流
-小结
--小结
-综合实例
--综合实例
-实验十一
--实验十一
- 第十一章讲义
-导学
--第12章导学
-异常处理的思想与程序实现
-第十二章 异常处理--异常处理的思想与程序实现
-异常处理中的构造与析构
-第十二章 异常处理--异常处理中的构造与析构
-标准程序库异常处理
-第十二章 异常处理--标准程序库异常处理
-小结
--第12章小结
-综合实例
--综合实例
-实验十二
--实验十二
- 第十二章讲义