1. 程式人生 > >《C++primer(第五版)》學習之路-第八章:IO庫

《C++primer(第五版)》學習之路-第八章:IO庫

宣告:版權所有,轉載請標明出處,請勿用於商業用途。聯絡信箱:[email protected]

8.1 IO類

1.

istream(輸入流)型別,提供輸入操作

ostream(輸出流)型別,提供輸出操作

cin,一個istream物件,從標準輸入讀取資料

cout,一個ostream物件,向標準輸出寫入資料

cerr,一個ostream物件,通常用於輸出程式錯誤資訊,寫入到標準錯誤

>>運算子,用來從一個istream物件讀取輸入資料

<<運算子,用來向一個ostream物件寫入輸出資料

getline函式,從一個給定的istream讀取一行資料,存入一個給定的string物件中

2.

IO 型別在三個獨立的標頭檔案中定義:
iostream 定義讀寫控制視窗的型別,
fstream 定義讀寫已命名檔案的型別,
sstream 所定義的型別則用於讀寫儲存在記憶體中的 string 物件。
在 fstream 和 sstream 裡定義的每種型別都是從iostream 標頭檔案中定義的相關型別派生而來。

3.IO庫型別和標頭檔案


4.IO庫條件狀態

strm::iostate     // 機器相關的整型名,由各個iostream類定義,用於定義條件狀態
strm::badbit      // strm::iostate型別的值,用於指出被破壞的流
strm::failbit       // strm::iostate型別的值,用於指出失敗的IO操作
strm::eofbit       // strm::iostate型別的值,用於指出流已經到達檔案結束符
s.eof()               // 如果設定了流s的eofbit值,則該函式返回true
s.fail()               // 如果設定了流s的failbit值,則該函式返回true
s.bad()              // 如果設定了流s的badbit值,則該函式返回true
s.good()            // 如果流s處於有效狀態,則該函式返回true
s.clear()            // 將流s中的所有狀態值都重設為有效狀態
s.clear(flag)      // 將流s中的某個指定條件狀態設定為有效。flag的型別是strm::iostate
s.setstate(flag) // 給流s新增指定條件。flag的型別是strm::iostate
s.rdstate()        // 返回流s的當前條件,返回值型別為strm::iostate


5.

導致緩衝重新整理的原因有很多:
1. 程式正常結束,作為main函式的return操作的一部分,緩衝重新整理被執行。
2. 緩衝區滿時,需要重新整理緩衝,而後新的資料才能繼續寫入緩衝區。
3.我們可以使用操縱符如endl來顯式重新整理緩衝區。
4. 在每次輸出操作完後,我們可以用操作符unitbuf設定流的內部狀態,從而清空緩衝區。預設情況下,對cerr是設定unitbuf的,因此寫到cerr的內容都是立即重新整理的。
5. 一個輸出流可能被關聯到另一個流。在這種情況下,當肚瀉被關聯的流時,關聯到的流的緩衝區會被重新整理。

6.重新整理輸出緩衝區

endl 操縱符,用於輸出一個換行符並重新整理緩衝區。
flush操縱符,用於重新整理流,但不在輸出中新增任何字元。
ends操作符,這個操縱符在緩衝區中插入空字元 null,然後後重新整理它。

7.

unitbuf操縱符,這個操縱符在每次執行完寫操作後都重新整理流。
nounitbuf操縱符將流恢復為使用正常的、由系統管理的緩衝區重新整理方式。

8.2 檔案輸入輸出

1.C++ 通過以下幾個類支援檔案的輸入輸出:
ofstream: 寫操作(輸出)的檔案類 (由ostream引申而來)
ifstream: 讀操作(輸入)的檔案類(由istream引申而來)
fstream: 可同時讀寫操作的檔案類 (由iostream引申而來)

2.檔案模式
in              開啟檔案做讀操作
out             開啟檔案做寫操作
app             在每次寫之前找到檔案尾
ate             開啟檔案後立即將檔案定位在檔案尾
trunc           開啟檔案時清空已存在的檔案流
binary          以二進位制模式進行 IO 操作

8.3 string流

1.標準庫定義了三種類型的字串流:
istringstream,由 istream 派生而來,提供讀 string 的功能。
ostringstream,由 ostream 派生而來,提供寫 string 的功能。
stringstream,由 iostream 派生而來,提供讀寫 string 的功能。

2.stringstream 特定的操作

sstream strm;              strm是一個未繫結的stringstream物件。sstream是標頭檔案sstream中定義的一個型別

sstream strm(s);          strm是一個sstream物件,儲存string s的一個拷貝。此建構函式是explict的。

strm.str()                     返回strm所儲存的string的拷貝

strm.str(s)                   將string s拷貝到strm中。返回void

PS:部分練習答案

練習8.1

istream& func(istream& is)
{
	std::string sbuf;
	while(is >> sbuf)
		std::cout << sbuf << std::endl;
	is.clear();
	return is;
}

練習8.2
#include <iostream>
using std::istream;

istream& func(istream& is)
{
	std::string sbuf;
	while(is >> sbuf)
		std::cout << sbuf << std::endl;
	is.clear();
	return is;
}

int main()
{
	istream& is = func(std::cin);
	std::cout << is.rdstate() << std::endl;
	
	return 0;
}

練習8.4
#include <fstream>
#include <string>
#include <vector>
#include <iostream>

using std::vector;
using std::string;
using std::ifstream;
using std::cout;
using std::endl;

void ReadFileToVec(const string& fileName,vector<string>& vec)
{
	ifstream ifs(fileName);
	if(ifs)
	{
		string buf;
		while(std::getline(ifs,buf))
			vec.push_back(buf);
	}
}

int main()
{
	vector<string> vec;
	ReadFileToVec("data.txt",vec);
	for(const auto& str:vec)
		cout << str << endl;
	return 0;
}

練習8.5

#include <fstream>
#include <string>
#include <vector>
#include <iostream>

using std::vector;
using std::string;
using std::ifstream;
using std::cout;
using std::endl;

void ReadFileToVec(const string& fileName,vector<string>& vec)
{
	ifstream ifs(fileName);
	if(ifs)
	{
		string buf;
		while(ifs >> buf)
			vec.push_back(buf);
	}
}

int main()
{
	vector<string> vec;
	ReadFileToVec("data.txt",vec);
	for(const auto& str:vec)
		cout << str << endl;
	return 0;
}

練習8.6
<pre name="code" class="cpp">#include <fstream>
#include <iostream>

#include "ex7_26.h"
using std::ifstream;
using std::cout;
using std::endl;
using std::cerr;

int main(int argc, char** argv)
{
	ifstream input(argv[1]);

	Sales_data total;
	if (read(input, total))
	{
		Sales_data trans;
		while (read(input, trans))
		{
			if (total.isbn() == trans.isbn())
				total.combine(trans);
			else
			{
				print(cout, total) << endl;
				total = trans;
			}
		}
		print(cout, total) << endl;
	}
	else
	{
		cerr << "No data?!" << endl;
	}

	return 0;
}


練習8.7
#include <fstream>
#include <iostream>

#include "ex7_26.h"
using std::ifstream;
using std::ofstream;
using std::endl;
using std::cerr;

int main(int argc, char** argv)
{
	ifstream input(argv[1]);
	ofstream output(argv[2]);

	Sales_data total;
	if (read(input, total))
	{
		Sales_data trans;
		while (read(input, trans))
		{
			if (total.isbn() == trans.isbn())
				total.combine(trans);
			else
			{
				print(output, total) << endl;
				total = trans;
			}
		}
		print(output, total) << endl;
	}
	else
	{
		cerr << "No data?!" << endl;
	}

	return 0;
}


練習8.8

#include <fstream>
#include <iostream>

#include "ex7_26.h"
using std::ifstream;
using std::ofstream;
using std::endl;
using std::cerr;

int main(int argc, char** argv)
{
	ifstream input(argv[1]);
	ofstream output(argv[2], ofstream::app);

	Sales_data total;
	if (read(input, total))
	{
		Sales_data trans;
		while (read(input, trans))
		{
			if (total.isbn() == trans.isbn())
				total.combine(trans);
			else
			{
				print(output, total) << endl;
				total = trans;
			}
		}
		print(output, total) << endl;
	}
	else
	{
		cerr << "No data?!" << endl;
	}

	return 0;
}

練習8.9
#include <iostream>
#include <sstream>
using std::istream;

istream& func(istream& is)
{
	std::string buf;
	while(is >> buf)
		std::cout << buf << std::endl;
	is.clear();
	return is;
}

int main()
{
	std::istringstream iss("hello word");
	func(iss);
	return 0;
}

練習8.10

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>

using std::vector;
using std::string;
using std::ifstream;
using std::istringstream;
using std::cout;
using std::endl;
using std::cerr;

int main()
{
	ifstream ifs("data.txt");
	if (!ifs)
	{
		cerr << "No data?" << endl;
		return -1;
	}

	vector<string> vecLine;
	string line;
	while (getline(ifs, line)) vecLine.push_back(line);

	for (auto& s : vecLine)
	{
		istringstream iss(s);
		string word;
		while (iss >> word)
			cout << word << endl;
	}

	return 0;
}

練習8.11

#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using std::vector;
using std::string;
using std::cin;
using std::istringstream;

struct PersonInfo
{
	string name;
	vector<string> phones;
};

int main()
{
	string line, word;
	vector<PersonInfo> people;
	istringstream record;
	while (getline(cin, line))
	{
		PersonInfo info;
		record.clear();
		record.str(line);
		record >> info.name;
		while (record >> word)
			info.phones.push_back(word);
		people.push_back(info);
	}

	for (auto& p : people)
	{
		std::cout << p.name << " ";
		for (auto& s : p.phones) std::cout << s << " ";
		std::cout << std::endl;
	}

	return 0;
}

練習8.13

#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>

using std::vector;
using std::string;
using std::cin;
using std::istringstream;
using std::ostringstream;
using std::ifstream;
using std::cerr;
using std::cout;
using std::endl;
using std::isdigit;

struct PersonInfo
{
	string name;
	vector<string> phones;
};

bool valid(const string& str)
{
	return isdigit(str[0]);
}

string format(const string& str)
{
	return str.substr(0, 3) + "-" + str.substr(3, 3) + "-" + str.substr(6);
}

int main()
{
	ifstream ifs("data.txt");
	if (!ifs)
	{
		cerr << "no phone numbers?" << endl;
		return -1;
	}

	string line, word;
	vector<PersonInfo> people;
	istringstream record;
	while (getline(ifs, line))
	{
		PersonInfo info;
		record.clear();
		record.str(line);
		record >> info.name;
		while (record >> word)
			info.phones.push_back(word);
		people.push_back(info);
	}
	for (const auto& entry : people)
	{
		ostringstream formatted, badNums;
		for (const auto& nums : entry.phones)
			if (!valid(nums))
				badNums << " " << nums;
			else
				formatted << " " << format(nums);
		if (badNums.str().empty())
			cout << entry.name << " " << formatted.str() << endl;
		else
			cerr << "input error: " << entry.name << " invalid number(s) " << badNums.str() << endl;
	}

	return 0;
}

相關推薦

C++primer()》學習-IO

【宣告:版權所有,轉載請標明出處,請勿用於商業用途。聯絡信箱:[email protected]】 8.1 IO類 1. istream(輸入流)型別,提供輸入操作 ostream(輸出

c++primer----學習筆記(十)Ⅱ

部分習題解答: 18.1: (a)range_error (b)exception 如果寫成throw p,則丟擲指標,是錯誤的18.2: 發生異常,所在塊之前的臨時變數都會被銷燬,v呼叫vector類的解構函式進行銷燬,並釋放相關記憶體;p指標會被銷燬,但p指向的記憶體是動態分配的,所以該記憶

c++ primer----學習筆記(十)Ⅰ

用於大型程式的工具:異常處理、名稱空間和多重繼承 特殊要求: 在獨立開發的子系統之間協同處理錯誤的能力 使用各種庫(可能包含獨立開發的庫)進行協同開發的能力 對比較複雜的應用概念建模的能力 1.異常處理: 異常處理機制允許程式中獨立開發的部分能夠在執行

c primer plus()編程練習-編程練習

兩個感嘆號 nal getchar putc 進制 類型 運算 pre 重做 1.編寫一個程序。該程序讀取輸入直到遇到#字符,然後報告讀取的空格數目、讀取的換行符數目以及讀取的所有其他字符數目。 #include<stdio.h> #include<ct

c primer plus()編程練習-編程練習

main tdi blog plus prim span int 統計 rime 1.設計一個程序,統計從輸入到文件結尾為止的字符數。 #include<stdio.h> int main(void){ int ch; int i; i

C++ Primer() IO

cor 三種 cer record info pre hide std 2-0 練習8.1:考察如何管理流的狀態 1 istream& func(istream& is) 2 { 3 string buf; 4 while ( is>

C++primer()》學習-十九特殊工具與技術

【宣告:版權所有,轉載請標明出處,請勿用於商業用途。聯絡信箱:[email protected]】 19.1 控制記憶體分配 1. 當我們使用一條new表示式時: string *sp

C++primer()》學習-十六模板與泛型程式設計

【宣告:版權所有,轉載請標明出處,請勿用於商業用途。聯絡信箱:[email protected]】 16.1 定義模板 1.模板定義以關鍵字template開始,後跟一個模板引數列表,這是一個逗號分隔的一個或多個模板引數的列表,用小於號(<)和大於號(&

C++primer()》學習-用於大型程式的工具

【宣告:版權所有,轉載請標明出處,請勿用於商業用途。聯絡信箱:libi[email protected]】 18.1 異常處理 1.異常處理機制允許程式中獨立開發的部分能夠在執行時就出現

c++ primer----學習筆記(十九)Ⅱ

部分習題解答: 19.1、19.2: #include <iostream> #include <cstdlib> using namespace std; void *operator new(size_t size) { cout << "new(

c++ primer----學習筆記(十九)Ⅰ

文章目錄 ==特殊工具與技術== 1.控制記憶體分配 1.1 過載new和delete 1.2 定位new表示式 2. 執行時型別識別 2.1 dynamic_cast運算子 2.2 typeid運算子

c++ primer----學習筆記(十三)Ⅰ

知識點: 拷貝控制操作:拷貝、移動、賦值和銷燬 在定義一個類時,我們可以顯式或隱式的定義在此型別的物件拷貝、賦值、移動、銷燬是做什麼,主要通過五種特殊的成員函式來完成這些操作:拷貝建構函式、拷貝複製運算子、移動建構函式、移動複製運算子和解構函式 1.拷貝建構函式: 定

c++ primer----學習筆記(十)Ⅰ

oop的核心思想是多型性。我們把具有繼承關係的多個型別稱為多型型別; 引用或指標的靜態型別與動態型別不同這一事實正是c++語言支援多型性的根本存在 當且僅當對通過指標或引用呼叫虛擬函式時,才會在執行時解析該呼叫,也只有在這種情況下物件的動態型別才有可能與靜態型別不同 一個派生類的函式如果覆蓋了某個繼承而來

c++ primer----學習筆記(十六)Ⅱ

部分習題解答: 16.1: 當呼叫template時,編譯器使用實參的型別來確定繫結到模板引數T的型別,之後編譯器利用推斷出的模板引數來例項化一個特定版本的函式 16.2: #ifndef COMPARE_H #define COMPARE_H template &

c++ primer 學習筆記-第二 變數和基本型別

本文為轉載,出處:https://blog.csdn.net/libin1105/article/details/48157115                              https://blog.csdn.net/sunhero2010/article/d

c++ primer----學習筆記(

1.空語句:最簡單的語句,只包含一個單獨的分號 複合語句:指用花括號括起來的語句和宣告的序列,複合語句也被稱為塊 2.if語句: //語法形式: if (condition) statement //if、else語句 if (condition) s

c++ primer 學習筆記-

本文為轉載,出處:https://blog.csdn.net/libin1105/article/details/48664019                                https://blog.csdn.net/sunhero2010/article

c++ primer 學習筆記- 字串、向量和陣列

本文為轉載,出處:https://blog.csdn.net/libin1105/article/details/48210261                               https://blog.csdn.net/fnoi2014xtx/article/

java學習--------

今天的內容主要就是隨機數的二種方式和有關隨機數的二個案例 1.Math方法 語法:Math.random();           生成的是0.0~1.0之間的隨機浮點數 備註:前包括後不包括0

java學習———

今天雖然寫的是第十五天,但是其實已經過了二個星期了,因為之前在做面向物件的專案,所以之前就沒有寫。 今天我們已經別了面向物件,已經學習到了Java核心——API 學習安排:兩週時間 內容:String類,正則表示式,日曆日期類,集合,IO流,異常,執行緒。 一,什麼是API &n