为什么80%的码农都做不了架构师?>>>   

写在前面:

说到流操作,则与程序的输入输出(简记为I/O)有关,本文讲述C++的一些I/O操作。本文所用的一些操作虽然都是基于标准输入输出(如屏幕和键盘到程序的输出和输入),但是这些规则对于接下来的文件操作也是有用的。C++ I/O 区分流的种类,特定种类的I/O只能处理特定数据类型的流,称作种类安全流机制(Type-safe IO)(Chap 13 13.1 p.g.416)

C++含有变量wchar_t,用来表示Unicode字符;char16_t和char32_t是分别限定Unicode大小的字符变量种类。(Chap 13 13.2 p.g.418)

几个常用的有关流操作的头文件: <iostream>:定义基本I/O对象,例如cin, cout, cerr(非缓冲流,立即被输出到输出设备)和clog <iomanip>:提供格式化流操作 <fstream>:用于文件处理的流操作(本章不涉及,在文件操作时会再提)

在流文件中,存在如下定义:

//在流编程中一般直接使用typedef定义的名称
typedef basic_istream<char> istream;
typedef basic_ostream<char> ostream;
typedef basic_iostream<char> iostream;

关于typedef参考: https://my.oschina.net/SamYjy/blog/912868

C++流结构图示如下:

关于void *的两个作用:

void *用于输出字符指针的地址

由于C++自动决定数据的类型,因此当碰到诸如输出char *的值(指针的值是地址)的情况时,就需要把指针转化为空指针再进行输出,例如:

#include <cstdlib>
#include <iostream>using namespace std;int main(int argc, char** argv) {const char *const words = "This is a sentence.";int num = 7;const int * const numPtr = &num;//输出char*的值所对应的内容:cout << "Content of words is: " << words << endl;cout << "Content of numPtr is: " << *numPtr << endl;//输出char*的值(是一个地址):cout << "Value of words is: " << static_cast< const void * >( words ) << endl;cout << "Value of numPtr is: " << numPtr << endl;cout << "Value of numPtr is: " << static_cast< const void * >( numPtr ) << endl;return 0;
}

  • put方法:输出单个字符串,可以层叠,用法例如:
cout.put('A').put('\n').put('B');

void *被隐式调用用于判定输入是否结束:

此时,void *往往被cin.get()方法隐式调用,以判断输入是否完成。例如:

//EOF为cin.get()隐式调用void *之后文件结束的返回值while ( ( character = cin.get() ) != EOF )cout.put( character );

其中,cin.get有5个不同类型的版本。详细见参考资料相应部分。此方法默认输入不固定长度,并且以空格符号为界定符,将输入赋值给指定char *变量。使用举例如下:

#include <iostream>using namespace std;int main()
{// create two char arrays, each with 80 elementsconst int SIZE = 80;char buffer1[ SIZE ];char buffer2[ SIZE ];char buffer3[ SIZE ];// use cin to input characters into buffer1cout << "Enter a sentence:" << endl;cin >> buffer1;// display buffer1 contentscout << "\nBuffer 1:" << buffer1 << endl;// use cin.get to input characters into buffer2cin.get( buffer2, SIZE, 'l' ); //如果界定符前一个字符是r,将字母r放回流中cin.putback('r');// display buffer2 contentscout << "Buffer 2:" << buffer2 << endl;int nextChar = cin.peek();cout << "Next char will be output is: " << (char)(nextChar) << endl;
/*使用如下两种方法可以清除流中不需要的多余数据:*///方法一://int input;//while(input = cin.get() != '\n')//By default, ignore method ignores 1 char only//cin.ignore(1); //此处可以不写1//方法二://fflush(stdin);cin.get( buffer3, SIZE );cout << "Buffer 3: " << buffer3 << endl;
} // end main

用于处理非格式化I/O的方法:read, write和gcount:

对于非格式化流,C++使用read函数向程序读入数据,使用write函数向输出(可能是屏幕或硬盘)写出数据,使用gcount统计上一个输入流的字符长度(输入不满char[] 大小时按实际输入长度确定)。举例如下:

#include <iostream>
using namespace std;int main()
{const int SIZE = 80;char buffer[ SIZE ]; // create array of 80 characters// use function read to input characters into buffercout << "Enter a sentence:" << endl;cin.read( buffer, 20 );cout << "Length of last in stream: " << cin.gcount() << endl;// use functions write and gcount to display buffer characterscout << endl << "The sentence entered was:" << endl;cout.write( buffer, cin.gcount() );cout << endl;
} // end main

流操作符简介

常用流函数:

  • setbase(int):设置输出数据的基数,此整数可以为2,8,10或16
  • setprecision(int) / cout.setprecision(int):设置输出小数的精度
  • setw(int) / cout.width(int) / cin.width(int):设置输出/输入的字符最大长度,输出超过最大长度的,则按照字符长度输出整个字符;而输入则最多读入最大长度的字符。详细情况见以下示例程序。
  • setfill(char) / cout.fill(char) :往往与setw搭配使用,在多余的空格处填充相应字符。

常用流操作常量一览:

示例程序:

#include <iostream>
#include <iomanip>using namespace std;int main()
{int widthValue = 4;char sentence[ 10 ];cout << "Enter a sentence:" << endl;cin.width( 6 ); // input only 5 characters from sentencecout << setfill('*');//or can be://cout.fill('*');// set field width, then display characters based on that width while ( cin >> sentence ) {cout << setw(widthValue ++);cout << sentence << endl;cout << "Length of output: " << oct << showbase << widthValue << endl;//Can also be://cout.width( widthValue++ );      cin.width(6);//Or can be: //cin >> setw( 6 ); // input 5 more characters from sentence} // end while
} // end main

输出解释:cin默认情况相当于cin.get(),碰到界定符为空格时停止从流中读入数据,并将空格符号作为下一次读入的第一个字符。由于单词member前五个字母以及它之前一个空格正好构成6个字符,达到了输入流限制的最大长度,因此字母r作为下一个输入流的起始被读入。同理可分析function的读入情况。

C++中,可以通过在程序运行前储存程序当前流操作符号状态,使用完毕后恢复的方式来避免粘性流操作符对于之后程序产生的可能影响,具体程序如下:

//储存当前流操作符状态:
ios_base::fmtflags originalFormat = cout.flags();//省略中间部分可能改变流操作符状态的部分
//......//恢复到原来的流操作符状态:
cout.flags(originalFormat);

C++中,可以通过cin.clear()使得输入流恢复到一个正常流的状态,限于篇幅,这一点本文不展开,详见参考资料(C++11 Chap 13.8 p.g.442)

在C++中,标准输入流往往总是在其相应输出流之后出现,目的是便于向用户提供交互信息后再采纳用户输入。对于其他一般的流,则可以通过

input.tie(&output);

的方式指定相应流运行的顺序。取消这样的顺序限定,可以使用

input.tie(0);

实现。

参考资料:

  1. CppReference - get method, URL: http://en.cppreference.com/w/cpp/io/basic_istream/get
  2. CppReference: I/O Manipulator: http://en.cppreference.com/w/cpp/io/manip
  3. Paul Deitel & Harvey Deitel, C++11程序设计(英文版)(第2版),本文中C++11括号所表示的资料

转载于:https://my.oschina.net/Samyan/blog/1204687

C++学习手记五:C++流操作相关推荐

  1. 安卓学习 Day23:文件流操作

    文件流操作 一.案例演示--文件操作 1.创建安卓应用 2.添加背景图片 3.字符串资源文件 4.主布局资源文件 5.在raw目录里创建文件 - test.txt 6.在assets目录里创建文件 - ...

  2. JAVA SE学习day_05: IO与流操作

    一.IO与流 以程序为主体,input(输入)是读.获取.使用输入流的过程,output(输出)是写.发送的过程. JAVA IO 标准的输入与输出 JAVA IO将读和写按照方向划分为: 输入:用于 ...

  3. 搜索引擎学习(五)Lucene操作索引

    一.代码分析 /*** Lucene入门* 操作索引*/ public class ManageIndex {public IndexWriter getIndexWriter() throws Ex ...

  4. git学习(五)分支操作和解决冲突

    分支的作用 协同开发 开发失败不会对主分支有影响 大胆创新 修复bug不会使得服务器停止工作(24小时网站而言) 创建新分支 在新建git,也就是git init时会自动创建master分支,也就是主 ...

  5. 我的python学习(五)文件操作、异常捕获

    读写.创建文件 文件的分类: 文本文件:基于字符编码,存储的是普通字符串,不包括字体.字号.样式.颜色等信息,可通过文本编辑器显示和编辑,例如txt文件: 二进制文件:基于值编码的,以字节形式存储,其 ...

  6. Direct3D学习手记五:纹理映射

    本文介绍纹理映射:将2D图像映射到3D物体上 纹理坐标: 使用纹理映射将图片贴到3D物体表面必须物体的顶点指定纹理坐标,最多指定8级纹理坐标,本次我们只使用一级 可以像以下方式定义定点格式: //自定 ...

  7. Python学习系列(五)(文件操作及其字典)

    Python学习系列(五)(文件操作及其字典) Python学习系列(四)(列表及其函数) 一.文件操作 1,读文件      在以'r'读模式打开文件以后可以调用read函数一次性将文件内容全部读出 ...

  8. PHP中的MySQLi扩展学习(五)MySQLI_STMT对象操作

    PHP中的MySQLi扩展学习(五)MySQLI_STMT对象操作 就像 PDO 中的 PDO_Statment 对象一样,MySQLI_STMT 对象也是一个预处理语句所形成的对象,专门用来操作 M ...

  9. java学习笔记16--I/O流和文件

    本文地址:http://www.cnblogs.com/archimedes/p/java-study-note16.html,转载请注明源地址. IO(Input  Output)流 IO流用来处理 ...

最新文章

  1. java 8 什么软件_Java 8你了解多少呢?Java之被人遗忘的Java 8的八个功能
  2. 创建Silverlight 1.0 開發環境
  3. 上网速度快的浏览器_2020年浏览器国内市场占有率排行榜
  4. Leetcode-184. 部门工资最高的员工
  5. LeetCode 168. Excel Sheet Column Title
  6. pandas自动创建文件夹_pandas快速入门
  7. MTK 驱动开发(43)---GPS问题分类--MTK ALPS GPS的特殊知识
  8. [转载] Python语言程序设计基础(第二版)嵩天等课后习题答案
  9. httpclient工具类,使用连接池实现
  10. 常用的数据库软件各自有什么特点?
  11. RAC修改IP(public/virtual/scan)
  12. matlab 低级图形错误,matlab图形底层错误(matlab崩溃前的数据恢复)
  13. 企业为什么需要BI报表工具?
  14. transformer中的位置嵌入
  15. python scratch unity怎么读_Python如何像scratch一样朗读文字?
  16. 软考题目快速学习法(个人笔记)
  17. 保姆级二进制安装高可用k8s集群文档(1.23.8)
  18. Akaban操作系统(3)-----不按套路出牌的开发
  19. Java 开源中文分词器Ansj 学习教程
  20. 使用CAXA建立螺纹

热门文章

  1. Charles抓包https(测试app的双向认证)
  2. 请重新认识你作为程序员的价值
  3. WebServices中使用cxf开发日志拦截器以及自定义拦截器
  4. AMD加载器实现笔记(四)
  5. VS2015自定义类模板的方法
  6. PyCharm 快捷操作
  7. Unity3D笔记 愤怒的小鸟六 弹弓发射小鸟
  8. PostgreSQL流复制之二:pgpool-II实现PostgreSQL数据库集群(转发+整理)
  9. matlab从工作区读取一维数组和结构体
  10. 03013_JDBC工具类