練習8.1:編寫函數。接受一個istream&參數,返回值類型也是istream&。此函數必須從給定流中讀取數據,直至遇到文件結束標識時停止。
- #include <iostream>
- #include <stdexcept>
- using std::istream;
- using std::cin;
- using std::cout;
- using std::cerr;
- using std::endl;
- using std::runtime_error;
- istream &f(istream &in)
- {
- int v;
- while(in >> v, !in.eof())
- {
- if(in.bad())
- throw runtime_error("IO Stream error.");
- if(in.fail())
- {
- cerr<<"Data error! Please try again."<<endl;
- in.clear();
- in.ignore(100, '\n');
- continue;
- }
- cout<< v <<endl;
- }
- in.clear();
- return in;
- }
- int main()
- {
- cout<<"Please input some numbers, enter Ctrl+Z to end"<<endl;
- f(cin);
- return 0;
- }
練習8.3:什么情況下,下面的while循環會終止?
while (cin >> i) /*. . .*/
遇到文件結束符,或者遇到了IO流錯誤或者讀入了無效數據。
練習8.4:編寫函數,以讀模式打開一個文件,將其內容讀入到一個string的vector中,將每一行作為一個獨立的元素存於vector中。
#include <iostream> #include <string> #include <fstream> #include <vector> using std::cout; using std::endl; using std::string; using std::ifstream; using std::cerr; using std::vector; int main() { ifstream in("data.txt"); if(!in) { cerr<<"Can't open the file."<<endl; return -1; } string line; vector<string> words; while(getline(in, line)) words.push_back(line); in.close(); vector<string>::const_iterator it = words.cbegin(); while (it != words.cend()) { cout<< *it <<endl; ++it; } return 0; }
練習8.5:重寫上面的程序,將每個單詞作為一個獨立的元素進行存儲。
#include <iostream> #include <string> #include <fstream> #include <vector> using std::cout; using std::endl; using std::string; using std::ifstream; using std::cerr; using std::vector; int main() { ifstream in("data.txt"); if(!in) { cerr<<"Can't open the file."<<endl; return -1; } string line; vector<string> words; while(in >> line) words.push_back(line); in.close(); vector<string>::const_iterator it = words.cbegin(); while (it != words.cend()) { cout<< *it <<endl; ++it; } return 0; }
練習8.6:重寫7.1.1節的書店程序,從一個文件中讀取交易記錄。將文件名作為一個參數傳遞給main。
- #include <iostream>
- #include <fstream>
- #include "Sales_data.h"
- using std::cout;
- using std::cerr;
- using std::ifstream;
- using std::endl;
- int main(int argc, char *argv[])
- {
- if (argc != 2) {
- cerr<< "Please give the file name."<<endl;
- return -1;
- }
- ifstream in(argv[1]);
- if (!in) {
- cerr<<"Can't open the file."<<endl;
- return -1;
- }
- Sales_data total;
- if (read(in, total)) {
- Sales_data trans;
- while(read(in ,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:修改上一節的書店程序,將結果保存到一個文件中。將輸出文件名作為第二個參數傳遞給main函數。
- #include <iostream>
- #include <fstream>
- #include "Sales_data.h"
- using std::cerr;
- using std::ifstream;
- using std::ofstream;
- using std::endl;
- int main(int argc, char *argv[])
- {
- if (argc != 3) {
- cerr<< "Please give the input file name and out file name."<<endl;
- return -1;
- }
- ifstream in(argv[1]);
- if (!in) {
- cerr<<"Can't open the file."<<endl;
- return -1;
- }
- ofstream out(argv[2]);
- if (!out) {
- cerr<<"can't open output file."<<endl;
- return -1;
- }
- Sales_data total;
- if (read(in, total)) {
- Sales_data trans;
- while(read(in ,trans)) {
- if(total.isbn() == trans.isbn())
- total.combine(trans);
- else {
- print(out, total) << endl;
- total =trans;
- }
- }
- print(out, total)<<endl;
- }
- else {
- cerr<<" No data?!"<<endl;
- }
- return 0;
- }
練習8.8:修改上一題的程序,將結果追加到給定的文件末尾。對同一個輸出文件,運行程序至少兩次,檢驗數據是否得以保留。
- #include <iostream>
- #include <fstream>
- #include "Sales_data.h"
- using std::cerr;
- using std::ifstream;
- using std::ofstream;
- using std::endl;
- int main(int argc, char *argv[])
- {
- if (argc != 3) {
- cerr<< "Please give the input file name and out file name."<<endl;
- return -1;
- }
- ifstream in(argv[1]);
- if (!in) {
- cerr<<"Can't open the file."<<endl;
- return -1;
- }
- ofstream out(argv[2], ofstream::app);
- if (!out) {
- cerr<<"can't open output file."<<endl;
- return -1;
- }
- Sales_data total;
- if (read(in, total)) {
- Sales_data trans;
- while(read(in ,trans)) {
- if(total.isbn() == trans.isbn())
- total.combine(trans);
- else {
- print(out, total) << endl;
- total =trans;
- }
- }
- print(out, total)<<endl;
- }
- else {
- cerr<<" No data?!"<<endl;
- }
- return 0;
- }
練習8.3.1:使用你為8.1.2節第一個練習所編寫的函數打印一個istringstream對象的內容。
- #include <iostream>
- #include <sstream>
- #include <string>
- #include <stdexcept>
- using std::istream;
- using std::ostringstream;
- using std::istringstream;
- using std::string;
- using std::cout;
- using std::cerr;
- using std::endl;
- using std::runtime_error;
- istream &f(istream &in)
- {
- int v;
- while(in >> v, !in.eof())
- {
- if(in.bad())
- throw runtime_error("IO Stream error.");
- if(in.fail())
- {
- cerr<<"Data error! Please try again."<<endl;
- in.clear();
- in.ignore(100, '\n');
- continue;
- }
- cout<< v <<endl;
- }
- in.clear();
- return in;
- }
- int main()
- {
- ostringstream msg;
- msg<<"C++ Primer 5th edition"<<endl;
- istringstream in(msg.str());
- f(in);
- return 0;
- }
練習8.10:編寫程序,將來自一個文件中的行保存在一個vector<string>中。然后使用一個istringstream從vector讀取數據元素,每次讀取一個單詞。
- #include <iostream>
- #include <fstream>
- #include <sstream>
- #include <string>
- #include <vector>
- using std::cerr;
- using std::endl;
- using std::cout;
- using std::ifstream;
- using std::istringstream;
- using std::string;
- using std::vector;
- int main()
- {
- ifstream in("Data.txt");
- if (!in) {
- cerr<<" Can't open input file."<<endl;
- return -1;
- }
- string line;
- vector<string> words;
- while (getline(in, line)) {
- words.push_back(line);
- }
- in.close();
- vector<string>::const_iterator it = words.begin();
- while( it != words.end()) {
- istringstream line_str(*it);
- string word;
- while(line_str >> word)
- cout<< endl;
- ++it;
- }
- return 0;
- }
練習8.11:本節的程序在外層while循環中定義了istringstream對象。如果record對象定義在循環之外,你需要對程序進行怎么樣的修改?重寫程序,將record的定義移到while循環之外,驗證你設想的修改方法是否正確。
- #include <iostream>
- #include <sstream>
- #include <string>
- #include <vector>
- using std::cin;
- using std::istringstream;
- using std::string;
- using std::vector;
- 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);
- }
- return 0;
- }
練習8.12:我們為什么沒有在PersonInfo中使用類內初始化?
由於每個人的電話號數量不固定,因此更好的方式不是通過類內初始化指定人名和所有電話號碼,而是在缺省初始化之后,在程序中設置人名並逐個添加電話號碼。
練習8.13:重寫本節的電話號碼程序,從一個命名文件而非cin讀取數據。
- #include <iostream>
- #include <fstream>
- #include <sstream>
- #include <string>
- #include <vector>
- using std::cerr;
- using std::endl;
- using std::cout;
- using std::ifstream;
- using std::istringstream;
- using std::ostringstream;
- using std::string;
- using std::vector;
- struct PersonInfo {
- string name;
- vector<string> phones;
- };
- string format(const string &s) { return s; }
- bool valid(const string &s)
- {
- return true;
- }
- int main(int argc, char *argv[])
- {
- string line, word;
- vector<PersonInfo> people;
- istringstream record;
- if (argc != 2) {
- cerr<<"Please give the file name."<<endl;
- return -1;
- }
- ifstream in(argv[1]);
- if(!in)
- {
- cerr<<"can't open input file"<<endl;
- return -1;
- }
- while (getline(in, line)) {
- PersonInfo info;
- record.clear();
- record.str(line);
- record >> info.name;
- while(record >> word)
- info.phones.push_back(word);
- people.push_back(info);
- }
- ostringstream os;
- 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())
- os <<entry.name<<" "<<formatted.str()<<endl;
- else
- cerr<<"input error: "<<entry.name<<" invalid number(s) "<<badNums.str()<<endl;
- }
- cout<<os.str()<<endl;
- return 0;
- }
練習8.14:我們為什么將entry和nums定義為const auto&?
這兩條語句分別適用范圍for語句枚舉people中所有項和每項的phones中的所有項。使用const表明在循環中不會改變這些項的值;auto是請求編譯器依據vector元素類型來推斷出entry和nums的類型,既簡化代碼又避免出錯;使用引用的原因是,people和phones的元素分別是結構對象和字符串對象,使用引用即可避免對象拷貝。
版權聲明:本文為博主原創文章,未經博主允許不得轉載。
練習8.1:編寫函數。接受一個istream&參數,返回值類型也是istream&。此函數必須從給定流中讀取數據,直至遇到文件結束標識時停止。
- #include <iostream>
- #include <stdexcept>
- using std::istream;
- using std::cin;
- using std::cout;
- using std::cerr;
- using std::endl;
- using std::runtime_error;
- istream &f(istream &in)
- {
- int v;
- while(in >> v, !in.eof())
- {
- if(in.bad())
- throw runtime_error("IO Stream error.");
- if(in.fail())
- {
- cerr<<"Data error! Please try again."<<endl;
- in.clear();
- in.ignore(100, '\n');
- continue;
- }
- cout<< v <<endl;
- }
- in.clear();
- return in;
- }
- int main()
- {
- cout<<"Please input some numbers, enter Ctrl+Z to end"<<endl;
- f(cin);
- return 0;
- }
練習8.3:什么情況下,下面的while循環會終止?
while (cin >> i) /*. . .*/
遇到文件結束符,或者遇到了IO流錯誤或者讀入了無效數據。
練習8.4:編寫函數,以讀模式打開一個文件,將其內容讀入到一個string的vector中,將每一行作為一個獨立的元素存於vector中。
- #include <iostream>
- #include <string>
- #include <fstream>
- #include <vector>
- using std::cout;
- using std::endl;
- using std::string;
- using std::ifstream;
- using std::cerr;
- using std::vector;
- int main()
- {
- ifstream in("data.txt");
- if(!in) {
- cerr<<"Can't open the file."<<endl;
- return -1;
- }
- string line;
- vector<string> words;
- while(getline(in, line))
- words.push_back(line);
- in.close();
- vector<string>::const_iterator it = words.cbegin();
- while (it != words.cend())
- {
- cout<< *it <<endl;
- ++it;
- }
- return 0;
- }
練習8.5:重寫上面的程序,將每個單詞作為一個獨立的元素進行存儲。
- #include <iostream>
- #include <string>
- #include <fstream>
- #include <vector>
- using std::cout;
- using std::endl;
- using std::string;
- using std::ifstream;
- using std::cerr;
- using std::vector;
- int main()
- {
- ifstream in("data.txt");
- if(!in) {
- cerr<<"Can't open the file."<<endl;
- return -1;
- }
- string line;
- vector<string> words;
- while(in >> line)
- words.push_back(line);
- in.close();
- vector<string>::const_iterator it = words.cbegin();
- while (it != words.cend())
- {
- cout<< *it <<endl;
- ++it;
- }
- return 0;
- }
練習8.6:重寫7.1.1節的書店程序,從一個文件中讀取交易記錄。將文件名作為一個參數傳遞給main。
- #include <iostream>
- #include <fstream>
- #include "Sales_data.h"
- using std::cout;
- using std::cerr;
- using std::ifstream;
- using std::endl;
- int main(int argc, char *argv[])
- {
- if (argc != 2) {
- cerr<< "Please give the file name."<<endl;
- return -1;
- }
- ifstream in(argv[1]);
- if (!in) {
- cerr<<"Can't open the file."<<endl;
- return -1;
- }
- Sales_data total;
- if (read(in, total)) {
- Sales_data trans;
- while(read(in ,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:修改上一節的書店程序,將結果保存到一個文件中。將輸出文件名作為第二個參數傳遞給main函數。
- #include <iostream>
- #include <fstream>
- #include "Sales_data.h"
- using std::cerr;
- using std::ifstream;
- using std::ofstream;
- using std::endl;
- int main(int argc, char *argv[])
- {
- if (argc != 3) {
- cerr<< "Please give the input file name and out file name."<<endl;
- return -1;
- }
- ifstream in(argv[1]);
- if (!in) {
- cerr<<"Can't open the file."<<endl;
- return -1;
- }
- ofstream out(argv[2]);
- if (!out) {
- cerr<<"can't open output file."<<endl;
- return -1;
- }
- Sales_data total;
- if (read(in, total)) {
- Sales_data trans;
- while(read(in ,trans)) {
- if(total.isbn() == trans.isbn())
- total.combine(trans);
- else {
- print(out, total) << endl;
- total =trans;
- }
- }
- print(out, total)<<endl;
- }
- else {
- cerr<<" No data?!"<<endl;
- }
- return 0;
- }
練習8.8:修改上一題的程序,將結果追加到給定的文件末尾。對同一個輸出文件,運行程序至少兩次,檢驗數據是否得以保留。
- #include <iostream>
- #include <fstream>
- #include "Sales_data.h"
- using std::cerr;
- using std::ifstream;
- using std::ofstream;
- using std::endl;
- int main(int argc, char *argv[])
- {
- if (argc != 3) {
- cerr<< "Please give the input file name and out file name."<<endl;
- return -1;
- }
- ifstream in(argv[1]);
- if (!in) {
- cerr<<"Can't open the file."<<endl;
- return -1;
- }
- ofstream out(argv[2], ofstream::app);
- if (!out) {
- cerr<<"can't open output file."<<endl;
- return -1;
- }
- Sales_data total;
- if (read(in, total)) {
- Sales_data trans;
- while(read(in ,trans)) {
- if(total.isbn() == trans.isbn())
- total.combine(trans);
- else {
- print(out, total) << endl;
- total =trans;
- }
- }
- print(out, total)<<endl;
- }
- else {
- cerr<<" No data?!"<<endl;
- }
- return 0;
- }
練習8.3.1:使用你為8.1.2節第一個練習所編寫的函數打印一個istringstream對象的內容。
- #include <iostream>
- #include <sstream>
- #include <string>
- #include <stdexcept>
- using std::istream;
- using std::ostringstream;
- using std::istringstream;
- using std::string;
- using std::cout;
- using std::cerr;
- using std::endl;
- using std::runtime_error;
- istream &f(istream &in)
- {
- int v;
- while(in >> v, !in.eof())
- {
- if(in.bad())
- throw runtime_error("IO Stream error.");
- if(in.fail())
- {
- cerr<<"Data error! Please try again."<<endl;
- in.clear();
- in.ignore(100, '\n');
- continue;
- }
- cout<< v <<endl;
- }
- in.clear();
- return in;
- }
- int main()
- {
- ostringstream msg;
- msg<<"C++ Primer 5th edition"<<endl;
- istringstream in(msg.str());
- f(in);
- return 0;
- }
練習8.10:編寫程序,將來自一個文件中的行保存在一個vector<string>中。然后使用一個istringstream從vector讀取數據元素,每次讀取一個單詞。
- #include <iostream>
- #include <fstream>
- #include <sstream>
- #include <string>
- #include <vector>
- using std::cerr;
- using std::endl;
- using std::cout;
- using std::ifstream;
- using std::istringstream;
- using std::string;
- using std::vector;
- int main()
- {
- ifstream in("Data.txt");
- if (!in) {
- cerr<<" Can't open input file."<<endl;
- return -1;
- }
- string line;
- vector<string> words;
- while (getline(in, line)) {
- words.push_back(line);
- }
- in.close();
- vector<string>::const_iterator it = words.begin();
- while( it != words.end()) {
- istringstream line_str(*it);
- string word;
- while(line_str >> word)
- cout<< endl;
- ++it;
- }
- return 0;
- }
練習8.11:本節的程序在外層while循環中定義了istringstream對象。如果record對象定義在循環之外,你需要對程序進行怎么樣的修改?重寫程序,將record的定義移到while循環之外,驗證你設想的修改方法是否正確。
- #include <iostream>
- #include <sstream>
- #include <string>
- #include <vector>
- using std::cin;
- using std::istringstream;
- using std::string;
- using std::vector;
- 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);
- }
- return 0;
- }
練習8.12:我們為什么沒有在PersonInfo中使用類內初始化?
由於每個人的電話號數量不固定,因此更好的方式不是通過類內初始化指定人名和所有電話號碼,而是在缺省初始化之后,在程序中設置人名並逐個添加電話號碼。
練習8.13:重寫本節的電話號碼程序,從一個命名文件而非cin讀取數據。
- #include <iostream>
- #include <fstream>
- #include <sstream>
- #include <string>
- #include <vector>
- using std::cerr;
- using std::endl;
- using std::cout;
- using std::ifstream;
- using std::istringstream;
- using std::ostringstream;
- using std::string;
- using std::vector;
- struct PersonInfo {
- string name;
- vector<string> phones;
- };
- string format(const string &s) { return s; }
- bool valid(const string &s)
- {
- return true;
- }
- int main(int argc, char *argv[])
- {
- string line, word;
- vector<PersonInfo> people;
- istringstream record;
- if (argc != 2) {
- cerr<<"Please give the file name."<<endl;
- return -1;
- }
- ifstream in(argv[1]);
- if(!in)
- {
- cerr<<"can't open input file"<<endl;
- return -1;
- }
- while (getline(in, line)) {
- PersonInfo info;
- record.clear();
- record.str(line);
- record >> info.name;
- while(record >> word)
- info.phones.push_back(word);
- people.push_back(info);
- }
- ostringstream os;
- 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())
- os <<entry.name<<" "<<formatted.str()<<endl;
- else
- cerr<<"input error: "<<entry.name<<" invalid number(s) "<<badNums.str()<<endl;
- }
- cout<<os.str()<<endl;
- return 0;
- }
練習8.14:我們為什么將entry和nums定義為const auto&?
這兩條語句分別適用范圍for語句枚舉people中所有項和每項的phones中的所有項。使用const表明在循環中不會改變這些項的值;auto是請求編譯器依據vector元素類型來推斷出entry和nums的類型,既簡化代碼又避免出錯;使用引用的原因是,people和phones的元素分別是結構對象和字符串對象,使用引用即可避免對象拷貝。
版權聲明:本文為博主原創文章,未經博主允許不得轉載。