1、标准库还提供了丰富的支持未格式化IO的低级操作,这些操作使我们能够将流作为未解释的字节序列处理,而不是作为数据类型(如char,int,string等)的序列处理。

2、单字节操作

几个未格式化的操作一次一个字节地处理流,它们不忽略空白地读。

示例代码

#include <iostream>
#include "string"
#include "cmath"
#include "iomanip"
using namespace std;int main()
{   //默认情况下,输入操作符忽略空白while(cin >> ch)cout << ch;//可以通过操纵符来强制不忽略空白cin >> noskipws;while(cin >> ch)cout << ch;cin >> skipws; //reset cin to default state so that it discards whitespace//通过未格式化的IO操作,我们一次一个字节处理流,不忽略空白while(cin.get(ch))cout.put(ch);return 1;
}

表1 单字节低级 IO 操作

is.get(ch)

将 istream is 的下一个字节放入 ch,返回 is

os.put(ch)

将字符 ch 放入 ostream,返回 os

is.get()

返回 is 的下一字节作为一个 int 值

is.putback(ch)

将字符 ch 放回 is,返回 is

is.unget()

将 is 退回一个字节,返回 is

is.peek()

将下一字节作为 int 值返回但不移出它

1)在流上倒退

一般而言,保证能够在下一次读之前放回最多一个值。也就是说,不保证能够连续调用 putback 或 unget 而没有介于其间的读操作。

标准库提供了三种方法来将字符放回流上:

• peek,返回输入流上下一字符的副本但不改变流。peek 返回的值留在流上,且将是下一个被检索的。

• unget,使输入流倒退,以便最后返回的值仍在流上。即使不知道最近从流获得的是什么值,也可以调用 unget。

• putback,unget 的更复杂的版本。它返回从流中读到的最后一个值,但接受最后一次读的同一实参。很少有程序使用 putback,因为更简单的unget 也可以完成相同工作而约束更少。

2)输入操作的int返回值

表1中函数返回int值是为了允许它们返回一个文件结束标记。这些函数将字符转换为unsigned char,然后将那个值提升为int,因此,即使字符集有映射到负值的字符,从这些操作返回的值也将是一个正值。通过将文件结束符作为负值返回,标准库保证文件结束符区别于任意合法字符值。

头文件iostream定义了名为EOF的const,可以使用它来测试函数的返回值是否为文件结束符。

示例代码

#include <iostream>
#include "string"
#include "cmath"
#include "iomanip"
using namespace std;int main()
{   int ch;while((ch = cin.get()) != EOF)cout.put(ch);return 1;
}

3、多字节操作

这些操作要求我们分配和管理用于存储和检索数据的字符数组。注意,get是重载的。

表2 多字节低级 IO 操作

is.get(sink, size, delim)

从 is 中读 size 个字节并将它们存储到 sink 所指向的字符数组中。读操作直到遇到 delim 字符,或已经读入了 size 个字节,或遇到文件结束符才结束。如果出现了 delim,就将它留在输入流上,不读入到 sink 中。

is.getline(sink, size, delim)

与三个实参的 get 行为类似,但读并丢弃 delim

is.read(sink, size)

读 size 个字节到数组 sink。返回 is

is.gcount()

返回最后一个未格式化读操作从流 is 中读到的字节数

os.write(source, size)

将 size 个字从数组 source 写至 os。返回 os

is.ignore(size, delim)

读并忽略至多 size 个字符,直到遇到 delim,但不包括 delim。默认情况下,size 是 1 而 delim 是文件结束符

将get或其他返回int值的函数的返回值赋给char对象而不是int对象,是常见的错误,但编译器不检测这样的错误。

1)get和getline进行读,起到遇到如下条件之一:

① 读到了size - 1个字符。

② 遇到文件结束符。

③ 遇到分隔符。

Following any of these conditions, a null character is put in the next open position in the array. The difference between these functions is the treatment of the delimiter. get leaves the delimiter as the next character of the istream . getline reads and discards the delimiter. In either case, the delimiter is not stored in sink .

2)有必要在任意插入的未格式化输入操作之前调用gcount。尤其是,将字符放回流上的单字符操作也是未格式化输入操作,如果在调用gcount之前调用peek、unget 或 putback,则返回值将是 0!

4、流的随机访问

IO类维持一个标记(位置指针),改标记决定下一个读或写发生在那里。

表3 seek和tell函数

seekg

重新定位输入流中的标记

tellg

返回输入流中标记的当前位置

seekp

重新定位输出流中的标记,seekp函数将位置置于下一个写将发生的地方

tellp

返回输出流中标记的当前位置

其中,p(ut),g(et)。

因为只有一个标记,所以,在读和写之间切换时必须进行seek来重新定位标记。同样,C语言也有这样的规定,读操作和写操作进行切换时,中间必须用fseek函数:

int fwrite(void *buf, int size, int count, FILE *fp)

int fseek(FILE *fp, LONG offset, int origin)

int fread(void *buf, int size, int count, FILE *fp)

1)普通iostream对象一般不允许随机访问。因为istream和ostream类型一般不支持随机访问,所以我们的seek,tell一般针对于fstream,和sstream。

2)seek的函数原形

原形定义

// set the indicated marker a fixed position within a file or string
seekg(new_position); // set read marker
seekp(new_position); // set write marker
// offset some distance from the indicated position
seekg(offset, dir); // set read marker
seekp(offset, dir); // set write marker

beg

The beginning of the stream

cur

The current position of the stream

end

The end of the stream

名为pos_type和off_type的类型分别表示位置和从该位置的偏移量。off_type类型的值可正可负,在文件中可以进行前向或后向seek。

示例代码

#include <iostream>
#include "string"
#include "cmath"
#include "iomanip"
using namespace std;int main()
{   ostringstream writerStr;ostringstream::pos_type mark = writerStr.tellp();//...if (cancelEntry)//return to marked positionwriterStr.seekp(mark);return 1;
}

3)在进行seek等函数前,应当调用流的clear()函数来清理流中的错误。这样防止流处于错误状态,而对文件流的操作都将失败。

示例代码

#include <iostream>
#include "string"
#include "cmath"
#include "iomanip"
#include "fstream"
using namespace std;int main()
{   //open for input and output and pre-position file pointers to end of filefstream inOut("C:\\httpdownload.txt", fstream::ate | fstream::in | fstream::out);if (!inOut){cerr << "Open file error" << endl;return EXIT_FAILURE;}//inOut is opened in ate mode, so it starts out positioned at the end,//which we must remember as it is the original end-of-file positionifstream::pos_type ptEndMark = inOut.tellg();inOut.seekg(0, fstream::beg);int cnt = 0;string line;// while we haven't hit an error and are still reading the original data// and successfully read another line from the filewhile(inOut && inOut.tellg() != ptEndMark && getline(inOut, line)){cnt += line.size() + 1;ifstream::pos_type ptCurrMark = inOut.tellg();inOut.seekp(0, fstream::end);inOut << cnt;if (ptCurrMark != ptEndMark)inOut << " ";inOut.seekg(ptCurrMark);}inOut.clear(); //clear flags in case we hit an errorinOut.seekp(0, fstream::end); // seek to endinOut << "\n"; //write a newline at end of filereturn 0;return 1;
}

42、C++ Primer 4th笔记,IO库,未格式化IO操作相关推荐

  1. C++primer第八章 IO库 8.1 IO类

    IO库设施 istream  (输入流)类型,提供输入操作. ostream (输出流)类型,提供输出操作. cin,-个 istream对象,从标准输入读取数据. cout, 一个ostream对象 ...

  2. C++Primer学习笔记:第8章 IO库

    C++语言不直接处理输入输出,而是通过一族定义在标准库中的类型来处理IO iostream定义了用于读写流的基本类型 fstream定义了读写命名文件的类型 sstream定义了读写内存string对 ...

  3. 29、C++ Primer 4th 笔记,异常处理

    1.类成员的指针不同于指向普通数据或函数的指针,普通指针只根据对象或函数的类型而变化,而成员的指针必须反映成员所属的类. 2.异常是通过抛出对象而引发的.该对象的类型决定应该激活哪个处理代码.被选中的 ...

  4. 24、C++ Primer 4th 笔记,面向对象编程(2)

    1.每个派生类对象包含一个基类部分.因此派生类对象也是基类对象.可以将派生类对象的引用转换为基类子对象的引用,同理指针. 2.没有从基类引用(或基类指针)到派生类引用(或派生类指针)的(自动)转换. ...

  5. 20、C++ Primer 4th 笔记,重载运算符(1)

    1.除了函数调用符之外,重载操作符的形参数目(包括成员函数的隐式this指针)与操作符的操作数目相同.函数调用操作符可以接受任意数目的操作数. 表1 可重载的操作符名 + - * / % ^ & ...

  6. 37、C++ Primer 4th笔记,特殊工具与技术,类成员指针

    1.成员指针(pointer to member)包含类的类型以及成员的类型.成员指针只应用于类的非static成员.static类成员不是任何对象的组成部分,所以不需要特殊语法来指向static成员 ...

  7. 38、C++ Primer 4th笔记,特殊工具与技术,嵌套类

    1.在一个类内部再定义另外一个类,这样的类称为嵌套类(nested class),也称为嵌套类型(nested type).嵌套类最常用于执行类. 嵌套类是独立的类,基本上与它们的外围类不相关,因此, ...

  8. Linux学习笔记-标准库中的管道操作

    目录 理论 例子 理论 stdio.h里面有标志库管道操作 FILE *popen(const char* cmdstring, const char *type);返回值:成功返回文件指针,出错返回 ...

  9. C++ Primer 5th笔记(chap 17 标准库特殊设施)多字节低层IO操作

    1. 多字节操作 一些未格式化 IO 操作一次处理大块数据,这些操作要求我们自己分配并管理用来保存和提取数据的字符数组 操作 解释 is.get(sink, size, delim) 从is中读取最多 ...

最新文章

  1. 机器学习从入门到精通系列之BP神经网络理论知识详解
  2. JS实现Echarts的图表保存为图片功能
  3. Java面试基础篇——第九篇:BIO,NIO,AIO的区别
  4. PHPstorm相同变量标识
  5. 电脑工具栏怎么调整到下面_雷电模拟器4.0怎么玩召唤与合成 一键下载轻松游玩 - 工具软件...
  6. OptaPlanner - 把example运行起来(运行并浅析Cloud balancing)
  7. 单链表实例之学生系统
  8. html5的交互标签,html5里交互元素的使用方法
  9. db2导入发生错误显示不是绝对路径_python编程常见错误总结
  10. FreeRTOS任务挂起与解除
  11. 集群搭建在一台计算机上,服务器集群
  12. FPGA浮点数定点数的处理
  13. SQL Server 2008空间数据应用系列十一:提取MapInfo地图数据中的空间数据解决方案...
  14. 绿色建筑评价标准(GB/T 50378-2006)
  15. 2020switch电信最快的dns_《2020switch电信最快的dns》电影_2020switch电信最快的dns正片免费观看-扬州人才服务网...
  16. mysql 中的any_value 函数
  17. matlab 球坐标系作图,使用Matlab的mapping tool在球坐标系下画图
  18. python爬取电影票房前50_Python3爬取起猫眼电影实时票房信息,解决文字反爬~~~附源代码...
  19. 无人驾驶汽车系统入门(十一)——深度前馈网络,深度学习的正则化,交通信号识别
  20. OSI七层模型功能及相关设备

热门文章

  1. Leetcode - Permutations I,II
  2. Hyper-V Server 虚拟光纤通道
  3. web测试知识点整理
  4. WindowsForm如何实现类似微软project软件的甘特图?
  5. 总结 15/4/23
  6. 7-1 defer调用
  7. html无序列表文字换行,ppwjs之bootstrap文字排版:无序列表项不换行
  8. 计算机毕业设计中基于Java和MySQL的图书管理系统
  9. matlab 箱图不显示异常值_欧姆龙E5EZ温控器PV显示值跳动异常的处理,一看就懂...
  10. 华为荣耀v8计算机没了,华为荣耀V8真机实测 没了徕卡到底咋样?