[c++primer][08]标准IO库

C++的输入/输出由标准库提供,支持对文件、控制窗口和string对象的读写。

8.1 面向对象的程序库

IO类型在三个独立的头文件中定义,iostream定义读写控制窗口的类型,fstream定义读写已命名文件的类型,sstream所定义的类型用于读写存储在内存中string对象。

如果函数有基类类型的引用形参时,可以给函数传递其派生类型的对象。即对istream&进行操作的函数,也可以使用ifstream或者istringstream对象来调用。

标准库定义了一组相关类型,支持wchar_t类型,每个类都加上“w”前缀,与char类型的版本区分。如wiostream、wfstream、wstringstream等。

IO对象不可复制或赋值

1)流对象不能复制,故不能存储在vector等容器中;

2)形参或返回类型不能为流类型。如要传递或返回IO对象,必须指定为该对象的指针或引用。

8.2 条件状态

条件状态

badbit标志着系统级的故障,无法恢复;failbit是IO错误,通常可以修正;eofbit是在遇到文件结束符时设置的,此时同时设置了failbit

bad、fail、eof中任意一个为true,则流处于错误状态;若三者都不为true,则good操作返回true。

clear操作将条件重设为有效状态。

setstate操作打开某个指定的条件,表示某个问题发生。

流状态的查询和控制

int ival;
// read cin and test only for EOF; loop is executed even if there are other IO failures
while (cin >> ival, !cin.eof()) {
    if (cin.bad()) // input stream is corrupted; bail out
        throw runtime_error("IO stream corrupted");
    if (cin.fail()) { // bad input
        cerr<< "bad data, try again"; // warn the user
        cin.clear(istream::failbit); // reset the stream
        continue; // get next input
    }
// ok to process ival
}    

条件状态的访问

rdstate成员函数返回一个iostate类型的值,表示流当前的整个条件状态。

// remember current state of cin
istream::iostate old_state = cin.rdstate();
cin.clear();
process_input(); // use cin
cin.clear(old_state); // now reset cin to old state

多种状态的处理

使用按位或在一次调用中生成“传递两个或更多状态位”的值

// sets both the badbit and the failbit
is.setstate(ifstream::badbit | ifstream::failbit);

生成一个值,对应于badbit和failbit的位都打开了,将这两个位都设置为1,该值的其他位都为0

8.3 输出缓冲区的管理

每个IO对象都管理一个缓冲区,用于存储程序读写的数据。下面几种情况会导致缓冲区的内容被刷新

1)程序正常结束

2)在一些不确定的时候,缓冲区已满,写入新数据前被刷新

3)用操纵符显式地刷新缓冲区

cout << "hi!" << flush; // flushes the buffer; adds no data
cout << "hi!" << ends; // inserts a null, then flushes the buffer
cout << "hi!" << endl; // inserts a newline, then flushes the buffer

4)每次操作执行完后,用unitbuf操纵符设置流的内部状态,从而清空缓冲区

cout << unitbuf << "first" << " second" << nounitbuf;
is equivalent to writing
cout << "first" << flush << " second" << flush;

unitbuf在每次执行完写操作后都刷新流,nonunitbuf操作符将流恢复为使用正常的、由系统管理的缓冲区刷新方式。

5)将输出流与输入流关联,在读输入流时将刷新其关联的输出缓冲区

标准库默认将cout与cin绑定在一起

tie函数可用istream或ostream调用,使用一个指向ostream对象的指针形参。如果在调用tie函数时传递实参0,则打破该流上已存在的捆绑。

cin.tie(&cout); // illustration only: the library ties cin and cout for us
ostream *old_tie = cin.tie();
cin.tie(0); // break tie to cout, cout no longer flushed when cin is read
cin.tie(&cerr); // ties cin and cerr, not necessarily a good idea!
// ...
cin.tie(0); // break tie between cin and cerr
cin.tie(old_tie); // restablish normal tie between cin and cout

8.4 文件的输入和输出

fstream除了继承下来的行为外,还定义了两个自己的新操作,open,close

流对象的两种初始化形式

// construct an ifstream and bind it to the file named ifile
ifstream infile(ifile.c_str());

ifstream infile; // unbound input file stream
infile.open("in"); // open file named "in" in the current directory

由于历史原因,IO标准库使用C风格字符串而不是C++ string类型的字符串作为文件名。

检查文件打开是否成功

// check that the open succeeded
if (!infile) {
    cerr << "error: unable to open input file: "
        << ifile << endl;
    return -1;
}

将文件流与新文件重新捆绑(文件流改变关联文件时,需先关闭当前的文件流)

ifstream infile("in"); // opens file named "in" for reading
infile.close(); // closes "in"
infile.open("next"); // opens file named "next" for reading

清除文件流的状态

重用已存在的流对象,while循环必须在每次循环时记得关闭和清空文件流,因成功打开文件并读取直到文件结束或出现其他错误为止,流对象处于错误状态,任何读取流对象的尝试都会失败。

ifstream input;
vector<string>::const_iterator it = files.begin();
// for each file in the vector
while (it != files.end()) {
    input.open(it->c_str()); // open the file
    // if the file is ok, read and "process" the input
    if (!input)
        break; // error: bail out!
    while(input >> s) // do the work on this file
        process(s);
    input.close(); // close file when we‘re done with it
    input.clear(); // reset state to ok
    ++it; // increment iterator to get next file
}    

文件模式

in 读打开,ifstream默认方式

out 写打开,ofstream默认方式,文件会被清空

app  末尾写打开

ate 打开定位到末尾

trunc 清空打开

binary 二进制形式打开

一个打开并检查输入文件的程序

// opens in binding it to the given file
ifstream& open_file(ifstream &in, const string &file)
{
    in.close(); // close in case it was already open
    in.clear(); // clear any existing errors
    // if the open fails, the stream will be in an invalid state
    in.open(file.c_str()); // open the file we were given
    return in; // condition state is good if open succeeded
}

8.5 字符串流

stringstream对象的使用

string line, word; // will hold a line and word from input, respectively
while (getline(cin, line)) { // read a line from the input into line
    // do per-line processing
    istringstream stream(line); // bind to stream to the line we read
    while (stream >> word){ // read a word from line
        // do per-word processing
    }
}

stringstream提供的转换

int val1 = 512, val2 = 1024;
ostringstream format_message;
// ok: converts values to a string representation
format_message << "val1: " << val1 << "\n"
                          << "val2: " << val2 << "\n";
// str member obtains the string associated with a stringstream
istringstream input_istring(format_message.str());
string dump; // place to dump the labels from the formatted message
// extracts the stored ascii values, converting back to arithmetic types
input_istring >> dump >> val1 >> dump >> val2;
cout << val1 << " " << val2 << endl; // prints 512 1024

使用输入操作符读string时,空白符将会忽略。

时间: 2024-08-11 10:19:01

[c++primer][08]标准IO库的相关文章

【C++ Primer | 08】IO库

IO类 C++的输入输出分为三种: (1)基于控制台的I/O (2)基于文件的I/O (3)基于字符串的I/O istringstream类 描述:从流中提取数据,支持 >> 操作 这里字符串可以包括多个单词,单词之间使用空格分开 1 #include <iostream> 2 #include <sstream> 3 using namespace std; 4 int main() 5 { 6 istringstream istr("1 56.7"

C++ Primer 读书笔记: 第8章 标准IO库

第8章 标准IO库 8.1 面向对象的标准库 1. IO类型在三个独立的头文件中定义:iostream定义读写控制窗口的类型,fstream定义读写已命名文件的类型,而sstream所定义的类型则用于读写存储在内存中的string对象.在fstream和sstream里定义的美中类型都是从iostream头文件中定义的相关类型派生而来. 2. 流对象不能复制,因此不能存储在vector容器中 3. 形参或返回类型也不能为流类型.如果需要传递或返回IO对象,则必须传递或返回指向该对象的指针或引用.

[APUE]标准IO库(下)

一.标准IO的效率 对比以下四个程序的用户CPU.系统CPU与时钟时间对比 程序1:系统IO 程序2:标准IO getc版本 程序3:标准IO fgets版本 结果: [注:该表截取自APUE,上表中"表3-1中的最佳时间即<程序1>","表3-1中的单字节时间指的是<程序1>中BUFSIZE为1时运行时间结果",fgetc/fputc版本程序这里没放出] 对于三个标准IO版本的每一个其用户CPU时间都大于最佳read版本,因为每次读一个字符

读书笔记-APUE第三版-(5)标准IO库

ISO C标准I/O库使用流的概念读写文件.流是对数据传输的抽象,可以把流理解为从起点到终点间的字节序列. 标准I/O库通过维护进程空间内的缓冲区,减少read/write系统调用次数来提高I/O效率.之前介绍的Unbuffered I/O和文件描述符fd打交道,标准I/O则使用FILE指针. typedef struct{ short level;/*缓冲区满程度*/ unsigned flags;/*文件打开状态标志*/ char fd;/*文件描述符*/ unsigned char hol

Unix环境之标准IO库

UNIX的文件IO都是针对文件描述符的,而标准IO的操作则是围绕流进行的.当一个流最初被创建时,它并没有定向.若在未定向的流上使用一个多字节IO函数,则将该流的定向设置为宽定向:若在未定向的流上使用一个单字节IO函数,则将该流的定向设置为字节定向. stdio.h定义了三个标准流,stdin.stdout和stderr,分别是标准输入.标准输出和标准出错. 缓冲-- 标准IO库提供缓冲的目的是尽可能减少使用read和write调用的次数.它也对每个IO流自动地进行缓冲管理,从而避免了应用程序需要

嵌入式 Linux系统编程(三)——标准IO库

嵌入式 Linux系统编程(三)--标准IO库 与文件IO函数相类似,标准IO库中提供的是fopen.fclose.fread.fwrite等面向流对象的IO函数,这些函数在实现时本身就要调用linux的文件IO这些系统调用. 一.标准IO库函数的缓冲机制 由于IO设备的访问速度与CPU的速度相差好几个数量级,为了协调IO设备与CPU的速度的不匹配,对于块设备,内核使用了页高速缓存,即数据会先被拷贝到操作系统内核的页缓存区中,然后才会从操作系统内核的缓存区拷贝到应用程序的地址空间. 当应用程序尝

文件IO函数和标准IO库的区别

摘自 http://blog.chinaunix.net/uid-26565142-id-3051729.html 1,文件IO函数,在Unix中,有如下5个:open,read,write,lseek,close.称之为不带缓存的IO(unbuffered I/O).不带缓存指的是每个read,write都调用内核中的一个系统调用. 2,标准IO库,由ANSI C标准说明.标准IO库处理很多细节.例如缓存分配,以优化长度执行IO等.标准的IO提供了三种类型的缓存. (1)全缓存:当填满标准IO

《UNIX环境高级编程》--5 标准IO库

标准IO库 流和 FILE对象 标准IO库与文件IO区别: 标准IO库处理很多细节,如缓冲区分片.以优化的块长度执行IO等. 文件IO函数都是围绕文件描述符进行.首先打开一个文件,返回一个文件描述符:后续的文件IO操作都使用该文件描述符 标准IO库是围绕流进行的.当用标准IO库打开或者创建一个文件时,就有一个内建的流与之相关联 标准IO库的函数很多都是以 f开头,如fopen.fclose 对于ASCII字符集,一个字符用一个字节表示:对于国际字符集,一个字符可以用多个字节表示. 标准IO文件流

C++标准IO库

概述 先不要急着知道怎么用这个玩意,让我们一起先来看一看C++标准IO库的框架,其实挺有意思的!那就开始吧! C++的输入输出由标准库提供,标准库提供了一族类型,支持对文件.string对象.和控制窗口等设备的读写.一方面,这些IO类型都定义了如何读写内置类型的的值,另一方面,用户在设计类时可以仿照IO标准库设施读写内置类型的方式设计自己的输入输出操作. 1. 面向对象的IO库 面向对象是C++的一大特色,他的标准库自然也不例外,统统都是面向对象设计的.标准库使用了继承(inheritance)