zoukankan      html  css  js  c++  java
  • 42、C++ Primer 4th笔记,IO库,未格式化IO操作

    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

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

    2)输入操作的int返回值

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

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

    示例代码

    #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对象,是常见的错误,但编译器不检测这样的错误。

    1getgetline进行读,起到遇到如下条件之一:

    ① 读到了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之前调用peekunget putback,则返回值将是 0

    4、流的随机访问

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

    3 seektell函数

    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对象一般不允许随机访问。因为istreamostream类型一般不支持随机访问,所以我们的seek,tell一般针对于fstream,sstream

    2seek的函数原形

    原形定义

    // 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_typeoff_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 position
    		writerStr.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 file
    	fstream 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 position
    	ifstream::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 file
    	while(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 error
    	inOut.seekp(0, fstream::end); // seek to end
    	inOut << "\n"; //write a newline at end of file
    	return 0;
    	return 1;
    }
    

  • 相关阅读:
    Java魔法堂:类加载器入了个门
    Java魔法堂:类加载机制入了个门
    FFDshow video encoder -CLSID
    在Ubuntu下利用Eclipse调试FFmpeg《转》
    vc/vs开发的应用程序添加dump崩溃日志<转>
    Directshow 采集与FFDshow 冲突
    dshow采集过程
    innosetup 安装前、卸载前判断是否有进程正在运行<转>
    手游加速器:[求助]安卓端 手游变速器,类似光环助手的实现方式是怎样的?
    网易云音乐api资料
  • 原文地址:https://www.cnblogs.com/mydomain/p/2060238.html
Copyright © 2011-2022 走看看