C++ primer 第八章-I/O library

Hi!这里是山幺幺的c++ primer系列。写这个系列的初衷是,虽然在学校学习了c++,但总觉得对这门语言了解不深,因此我想来啃啃著名的c++ primer,并在这里同步记录我的学习笔记。由于我啃的是英文版,所以笔记是中英文夹杂的那种。另外由于已有一定的编程基础,所以这个系列不会含有太基础的知识,想入门的朋友最好自己啃书嘻嘻~

I/O Classes


I/O library types

PS:w开头的类:To support languages that use wide characters, the library defines a set of types and objects that manipulate wchar_t data

  • ifstream and istringstream inherit from istream
  • ofstream and ostringstream inherit from ostream

I/O Objects的限制

  • No Copy or Assign for I/O Objects,因此parameter or return type都不能是I/O type
  • reading or writing an I/O object changes its state, so the reference to I/O objects must not be const

I/O Library Condition State

  • I/O objects will be in an error state if 输入的对象类型与期待的类型不匹配等
  • Once an error has occurred, subsequent IO operations on that stream will fail. We can read from or write to a stream only when it is in a non-error state.
  • The IO library defines a machine-dependent integral type named iostate,该类型有四个值:
    • badbit:indicates a system-level failure, such as an unrecoverable read or write error.
    • failbit:is set after a recoverable error, such as reading a character when numeric data was expected.
    • eofbit:reaching end-of -file sets both eofbit and failbit.
    • goodbit:guaranteed to have the value 0, indicates no failures on the stream.

PS:If any of badbit, failbit, or eofbit are set, then a condition that evaluates that stream will fail.

  • 栗子
// turns off failbit and badbit but all other bits unchanged
cin.clear(cin.rdstate() & ~cin.failbit & ~cin.badbit);

output buffer

  • buffer的作用:Using a buffer allows the operating system to combine several output operations from our program into a single system-level write,从而提升性能

  • flush buffer(即buffer中内容全部输出)的时机:

    • The program completes normally. All output buffers are flushed as part of the return from main
    • buffer满了之后will be flushed before writing the next value
    • We can flush the buffer explicitly using a manipulator
    cout << "hi!" << endl; // writes hi and a newline, then flushes the buffer
    cout << "hi!" << flush; // writes hi, then flushes the buffer; adds no data
    cout << "hi!" << ends; // writes hi and a null, then flushes the buffer
    
    • 可以用unitbuf把stream的state设置为empty the buffer after each output operation:By default, unitbuf is set for cerr, so that writes to cerr are flushed immediately
    cout << unitbuf; // all writes will be flushed immediately
    cout << nounitbuf; // returns to normal buffering
    
    • the buffer of the tied stream is flushed whenever the tied stream is read or written.
      • By default, cin and cerr are both tied to cout. Hence, reading cin or writing to cerr flushes the buffer in cout.
      cin >> ival; // causes the buffer associated with cout to be flushed.
      
      • We can tie either an istream or an ostream object to another ostream;一个istream/ostream只能 be tied to 一个ostream
      ostream *p = cin.tie(); // p points to the stream (if any) currently tied to cin, 若无则p = nullptr
      cin.tie(&cout); // illustration only: the library ties cin and cout for us
      // old_tie points to the stream (if any) currently tied to cin
      ostream *old_tie = cin.tie(nullptr); // cin is no longer tied
      cin.tie(&cerr); // reading cin flushes cerr, not cout
      cin.tie(old_tie); // reestablish normal tie between cin and cout
      

PS:Output buffers are not flushed if the program terminates abnormally.

文件I/O


file I/O types

  • ifstream:read from a given file
  • ofstream:write to a given file
  • fstream:reads and writes a given file
    PS:这些类型继承了iostream types的操作,比如<< >> getline等;所有可以使用iostream types的地方都可以使用对应的file I/O types

fstream-Specific Operations

  • 除了从iostream继承的操作,file I/O types还支持以下操作:

定义file I/O对象

  • 栗子(filename可以是string or C-style character array)
ifstream in(ifile); // construct an ifstream and open the given file
ofstream out; // output file stream that is not associated with any file

open和close

  • open

    • 用法
    ofstream out; // output file stream that is not associated with any file
    out.open(ifile + ".copy"); // open the specified file
    if (out) { ... }
    
    • Once a file stream has been opened, it remains associated with the specified file
    • calling open on a file stream that is already open will fail and set failbit
  • close

    • 用法
    in.close(); // close the file
    in.open(ifile + "2"); // open another file
    
    • To associate a file stream with a different file, we must first close the existing file. Once the file is closed, we can open a new one
    • When an fstream object is destroyed, close is called automatically

File Mode

  • out may be set only for an ofstream or fstream object
  • in may be set only for an ifstream or fstream object
  • trunc may be set only when out is also specified
  • app mode may be specified so long as trunc is not. If app is specified, the file is always opened in output mode, even if out was not explicitly specified
  • By default, a file opened in out mode is truncated even if we do not specify
    trunc. By default, when we open an ofstream, the contents of the file are discarded
  • To preserve the contents of a file opened with out, either we must also specify app, in which case we can write only at the end of the file, or we must also specify in, in which case the file is open for both input and output
  • The ate and binary modes may be specified on any file stream object type
    and in combination with any other file modes
  • 默认模式:Files associated with an ifstream are opened in in mode; files associated with an ofstream are opened in out mode; and files associated with an fstream are opened with both in and out modes
  • 栗子
// file1 is truncated in each of these cases
ofstream out("file1"); // out and trunc are implicit
ofstream out2("file1", ofstream::out); // trunc is implicit
ofstream out3("file1", ofstream::out | ofstream::trunc);
// to preserve the file's contents, we must explicitly specify app mode
ofstream app("file2", ofstream::app); // out is implicit
ofstream app2("file2", ofstream::out | ofstream::app);

string Streams


特点

  • in-memory IO
  • read from or write to a string as if the string were an IO stream

类型

  • istringstream:reads a string
  • ostringstream:writes a string
  • stringstream:reads and writes the string
    PS:这些类型继承了iostream types的操作,比如<< >> getline等;所有可以使用iostream types的地方都可以使用对应的string streams types

sstream-Specific Operations

  • 除了从iostream继承的操作,string streams types还支持以下操作:

栗子

  • istringstream
    要读的文件如下
    morgan 2015552368 8625550123
    drew 9735550130
    lee 6095550132 2015550175 8005550000
struct PersonInfo {
  string name;
  vector<string> phones;
};

string line, word;
vector<PersonInfo> people; // will hold all the records from the input
// read the input a line at a time until cin hits end-of-file (or another error)
while (getline(cin, line)) {
  PersonInfo info; // create an object to hold this record's data
  istringstream record(line); // bind record to the line we just read
  record >> info.name; // read the name
  while (record >> word) // read the phone numbers
    info.phones.push_back(word); // and store them
  people.push_back(info); // append this record to people
  }
  • ostringstream
for (const auto &entry : people) { // for each entry in people
  ostringstream formatted, badNums; // objects created on each loop
  for (const auto &nums : entry.phones) { // for each number
    if (!valid(nums)) {
      badNums << " " << nums; // string in badNums
    } else
    // ''writes'' to formatted's string
    formatted << " " << format(nums);
  }
  if (badNums.str().empty()) // there were no bad numbers
    os << entry.name << " " // print the name
        << formatted.str() << endl; // and reformatted numbers
  else // otherwise, print the name and bad numbers
    cerr << "input error: " << entry.name
            << " invalid number(s) " << badNums.str() << endl;
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,137评论 6 511
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,824评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,465评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,131评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,140评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,895评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,535评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,435评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,952评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,081评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,210评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,896评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,552评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,089评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,198评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,531评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,209评论 2 357