C++中文件的讀取操作,如何讀取多行數據,如何一個一個的讀取數據


練習8.1:編寫函數。接受一個istream&參數,返回值類型也是istream&。此函數必須從給定流中讀取數據,直至遇到文件結束標識時停止。

 

  1. #include <iostream>  
  2. #include <stdexcept>  
  3.   
  4. using std::istream;  
  5. using std::cin;  
  6. using std::cout;  
  7. using std::cerr;  
  8. using std::endl;  
  9. using std::runtime_error;  
  10.   
  11. istream &f(istream &in)  
  12. {  
  13.     int v;  
  14.     while(in >> v, !in.eof())  
  15.     {  
  16.         if(in.bad())  
  17.             throw runtime_error("IO Stream error.");  
  18.         if(in.fail())  
  19.         {  
  20.             cerr<<"Data error! Please try again."<<endl;  
  21.             in.clear();  
  22.             in.ignore(100, '\n');  
  23.             continue;  
  24.         }  
  25.         cout<< v <<endl;  
  26.     }  
  27.     in.clear();  
  28.     return in;  
  29. }  
  30.   
  31. int main()  
  32. {  
  33.     cout<<"Please input some numbers, enter Ctrl+Z to end"<<endl;  
  34.     f(cin);  
  35.     return 0;  
  36. }  

練習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。

 

  1. #include <iostream>  
  2. #include <fstream>  
  3. #include "Sales_data.h"  
  4.   
  5. using std::cout;  
  6. using std::cerr;  
  7. using std::ifstream;  
  8. using std::endl;  
  9.   
  10. int main(int argc, char *argv[])  
  11. {  
  12.     if (argc != 2) {  
  13.         cerr<< "Please give the file name."<<endl;  
  14.         return -1;  
  15.     }  
  16.     ifstream in(argv[1]);  
  17.     if (!in) {  
  18.         cerr<<"Can't open the file."<<endl;  
  19.         return -1;  
  20.     }  
  21.   
  22.     Sales_data total;  
  23.     if (read(in, total)) {  
  24.         Sales_data trans;  
  25.         while(read(in ,trans)) {  
  26.             if(total.isbn() == trans.isbn())  
  27.                 total.combine(trans);  
  28.             else {  
  29.                 print(cout, total) << endl;  
  30.                 total =trans;  
  31.             }  
  32.         }  
  33.         print(cout, total)<<endl;  
  34.     }  
  35.     else {  
  36.         cerr<<" No data?!"<<endl;  
  37.     }  
  38.     return 0;  
  39. }  

練習8.7:修改上一節的書店程序,將結果保存到一個文件中。將輸出文件名作為第二個參數傳遞給main函數。

 

  1. #include <iostream>  
  2. #include <fstream>  
  3. #include "Sales_data.h"  
  4.   
  5. using std::cerr;  
  6. using std::ifstream;  
  7. using std::ofstream;  
  8. using std::endl;  
  9.   
  10. int main(int argc, char *argv[])  
  11. {  
  12.     if (argc != 3) {  
  13.         cerr<< "Please give the input file name and out file name."<<endl;  
  14.         return -1;  
  15.     }  
  16.     ifstream in(argv[1]);  
  17.     if (!in) {  
  18.         cerr<<"Can't open the file."<<endl;  
  19.         return -1;  
  20.     }  
  21.     ofstream out(argv[2]);  
  22.     if (!out) {  
  23.         cerr<<"can't open output file."<<endl;  
  24.         return -1;  
  25.     }  
  26.   
  27.     Sales_data total;  
  28.     if (read(in, total)) {  
  29.         Sales_data trans;  
  30.         while(read(in ,trans)) {  
  31.             if(total.isbn() == trans.isbn())  
  32.                 total.combine(trans);  
  33.             else {  
  34.                 print(out, total) << endl;  
  35.                 total =trans;  
  36.             }  
  37.         }  
  38.         print(out, total)<<endl;  
  39.     }  
  40.     else {  
  41.         cerr<<" No data?!"<<endl;  
  42.     }  
  43.     return 0;  
  44. }  


練習8.8:修改上一題的程序,將結果追加到給定的文件末尾。對同一個輸出文件,運行程序至少兩次,檢驗數據是否得以保留。

 

  1. #include <iostream>  
  2. #include <fstream>  
  3. #include "Sales_data.h"  
  4.   
  5. using std::cerr;  
  6. using std::ifstream;  
  7. using std::ofstream;  
  8. using std::endl;  
  9.   
  10. int main(int argc, char *argv[])  
  11. {  
  12.     if (argc != 3) {  
  13.         cerr<< "Please give the input file name and out file name."<<endl;  
  14.         return -1;  
  15.     }  
  16.     ifstream in(argv[1]);  
  17.     if (!in) {  
  18.         cerr<<"Can't open the file."<<endl;  
  19.         return -1;  
  20.     }  
  21.     ofstream out(argv[2], ofstream::app);  
  22.     if (!out) {  
  23.         cerr<<"can't open output file."<<endl;  
  24.         return -1;  
  25.     }  
  26.   
  27.     Sales_data total;  
  28.     if (read(in, total)) {  
  29.         Sales_data trans;  
  30.         while(read(in ,trans)) {  
  31.             if(total.isbn() == trans.isbn())  
  32.                 total.combine(trans);  
  33.             else {  
  34.                 print(out, total) << endl;  
  35.                 total =trans;  
  36.             }  
  37.         }  
  38.         print(out, total)<<endl;  
  39.     }  
  40.     else {  
  41.         cerr<<" No data?!"<<endl;  
  42.     }  
  43.     return 0;  
  44. }  

練習8.3.1:使用你為8.1.2節第一個練習所編寫的函數打印一個istringstream對象的內容。

 

  1. #include <iostream>  
  2. #include <sstream>  
  3. #include <string>  
  4. #include <stdexcept>  
  5.   
  6. using std::istream;  
  7. using std::ostringstream;  
  8. using std::istringstream;  
  9. using std::string;  
  10. using std::cout;  
  11. using std::cerr;  
  12. using std::endl;  
  13. using std::runtime_error;  
  14.   
  15. istream &f(istream &in)  
  16. {  
  17.     int v;  
  18.     while(in >> v, !in.eof())  
  19.     {  
  20.         if(in.bad())  
  21.             throw runtime_error("IO Stream error.");  
  22.         if(in.fail())  
  23.         {  
  24.             cerr<<"Data error! Please try again."<<endl;  
  25.             in.clear();  
  26.             in.ignore(100, '\n');  
  27.             continue;  
  28.         }  
  29.         cout<< v <<endl;  
  30.     }  
  31.     in.clear();  
  32.     return in;  
  33. }  
  34.   
  35. int main()  
  36. {  
  37.     ostringstream msg;  
  38.     msg<<"C++ Primer 5th edition"<<endl;  
  39.     istringstream in(msg.str());  
  40.     f(in);  
  41.     return 0;  
  42. }  

練習8.10:編寫程序,將來自一個文件中的行保存在一個vector<string>中。然后使用一個istringstream從vector讀取數據元素,每次讀取一個單詞。
  1. #include <iostream>  
  2. #include <fstream>  
  3. #include <sstream>  
  4. #include <string>  
  5. #include <vector>  
  6.   
  7. using std::cerr;  
  8. using std::endl;  
  9. using std::cout;  
  10. using std::ifstream;  
  11. using std::istringstream;  
  12. using std::string;  
  13. using std::vector;  
  14.   
  15. int main()  
  16. {  
  17.     ifstream in("Data.txt");  
  18.     if (!in) {  
  19.         cerr<<" Can't open input file."<<endl;  
  20.         return -1;  
  21.     }  
  22.   
  23.     string line;  
  24.     vector<string> words;  
  25.     while (getline(in, line)) {  
  26.         words.push_back(line);  
  27.     }  
  28.     in.close();  
  29.   
  30.     vector<string>::const_iterator it = words.begin();  
  31.     while( it != words.end()) {  
  32.         istringstream line_str(*it);  
  33.         string word;  
  34.         while(line_str >> word)  
  35.             cout<< endl;  
  36.         ++it;  
  37.     }  
  38.   
  39.     return 0;  
  40. }  

練習8.11:本節的程序在外層while循環中定義了istringstream對象。如果record對象定義在循環之外,你需要對程序進行怎么樣的修改?重寫程序,將record的定義移到while循環之外,驗證你設想的修改方法是否正確。

 

  1. #include <iostream>  
  2. #include <sstream>  
  3. #include <string>  
  4. #include <vector>  
  5.   
  6. using std::cin;  
  7. using std::istringstream;  
  8. using std::string;  
  9. using std::vector;  
  10.   
  11. struct PersonInfo {  
  12.     string name;  
  13.     vector<string> phones;  
  14. };  
  15.   
  16. int main()  
  17. {  
  18.     string line, word;  
  19.     vector<PersonInfo> people;  
  20.     istringstream record;  
  21.   
  22.     while (getline(cin,line)) {  
  23.         PersonInfo info;  
  24.         record.clear();  
  25.         record.str(line);  
  26.         record >> info.name;  
  27.         while (record >> word)  
  28.             info.phones.push_back(word);  
  29.   
  30.     people.push_back(info);  
  31.     }  
  32.   
  33.     return 0;  
  34. }  

練習8.12:我們為什么沒有在PersonInfo中使用類內初始化?

由於每個人的電話號數量不固定,因此更好的方式不是通過類內初始化指定人名和所有電話號碼,而是在缺省初始化之后,在程序中設置人名並逐個添加電話號碼。


練習8.13:重寫本節的電話號碼程序,從一個命名文件而非cin讀取數據。

 

  1. #include <iostream>  
  2. #include <fstream>  
  3. #include <sstream>  
  4. #include <string>  
  5. #include <vector>  
  6.   
  7. using std::cerr;  
  8. using std::endl;  
  9. using std::cout;  
  10. using std::ifstream;  
  11. using std::istringstream;  
  12. using std::ostringstream;  
  13. using std::string;  
  14. using std::vector;  
  15.   
  16. struct PersonInfo {  
  17.     string name;  
  18.     vector<string> phones;  
  19. };  
  20.   
  21. string format(const string &s) { return s; }  
  22.   
  23. bool valid(const string &s)  
  24. {  
  25.     return true;  
  26. }  
  27.   
  28. int main(int argc, char *argv[])  
  29. {  
  30.     string line, word;  
  31.     vector<PersonInfo> people;  
  32.     istringstream record;  
  33.   
  34.     if (argc != 2) {  
  35.         cerr<<"Please give the file name."<<endl;  
  36.         return -1;  
  37.     }  
  38.     ifstream in(argv[1]);  
  39.     if(!in)  
  40.     {  
  41.         cerr<<"can't open input file"<<endl;  
  42.         return -1;  
  43.     }  
  44.   
  45.     while (getline(in, line)) {  
  46.         PersonInfo info;  
  47.         record.clear();  
  48.         record.str(line);  
  49.         record >> info.name;  
  50.         while(record >> word)  
  51.             info.phones.push_back(word);  
  52.   
  53.         people.push_back(info);  
  54.   
  55.     }  
  56.   
  57.     ostringstream os;  
  58.     for (const auto &entry : people) {  
  59.         ostringstream formatted, badNums;  
  60.         for(const auto &nums : entry.phones) {  
  61.             if (!valid(nums)) {  
  62.                 badNums << " "<< nums;  
  63.             }  
  64.             else  
  65.                 formatted << " " <<format(nums);  
  66.         }  
  67.         if (badNums.str().empty())  
  68.             os <<entry.name<<" "<<formatted.str()<<endl;  
  69.         else  
  70.             cerr<<"input error: "<<entry.name<<" invalid number(s) "<<badNums.str()<<endl;  
  71.     }  
  72.     cout<<os.str()<<endl;  
  73.   
  74.     return 0;  
  75. }  

練習8.14:我們為什么將entry和nums定義為const auto&?

這兩條語句分別適用范圍for語句枚舉people中所有項和每項的phones中的所有項。使用const表明在循環中不會改變這些項的值;auto是請求編譯器依據vector元素類型來推斷出entry和nums的類型,既簡化代碼又避免出錯;使用引用的原因是,people和phones的元素分別是結構對象和字符串對象,使用引用即可避免對象拷貝。

 
 

 

練習8.1:編寫函數。接受一個istream&參數,返回值類型也是istream&。此函數必須從給定流中讀取數據,直至遇到文件結束標識時停止。

 

  1. #include <iostream>  
  2. #include <stdexcept>  
  3.   
  4. using std::istream;  
  5. using std::cin;  
  6. using std::cout;  
  7. using std::cerr;  
  8. using std::endl;  
  9. using std::runtime_error;  
  10.   
  11. istream &f(istream &in)  
  12. {  
  13.     int v;  
  14.     while(in >> v, !in.eof())  
  15.     {  
  16.         if(in.bad())  
  17.             throw runtime_error("IO Stream error.");  
  18.         if(in.fail())  
  19.         {  
  20.             cerr<<"Data error! Please try again."<<endl;  
  21.             in.clear();  
  22.             in.ignore(100, '\n');  
  23.             continue;  
  24.         }  
  25.         cout<< v <<endl;  
  26.     }  
  27.     in.clear();  
  28.     return in;  
  29. }  
  30.   
  31. int main()  
  32. {  
  33.     cout<<"Please input some numbers, enter Ctrl+Z to end"<<endl;  
  34.     f(cin);  
  35.     return 0;  
  36. }  

練習8.3:什么情況下,下面的while循環會終止?

while (cin >> i) /*. . .*/

遇到文件結束符,或者遇到了IO流錯誤或者讀入了無效數據。


練習8.4:編寫函數,以讀模式打開一個文件,將其內容讀入到一個string的vector中,將每一行作為一個獨立的元素存於vector中。

 

  1. #include <iostream>  
  2. #include <string>  
  3. #include <fstream>  
  4. #include <vector>  
  5. using std::cout;  
  6. using std::endl;  
  7. using std::string;  
  8. using std::ifstream;  
  9. using std::cerr;  
  10. using std::vector;  
  11.   
  12. int main()  
  13. {  
  14.     ifstream in("data.txt");  
  15.     if(!in) {  
  16.         cerr<<"Can't open the file."<<endl;  
  17.         return -1;  
  18.     }  
  19.   
  20.     string line;  
  21.     vector<string> words;  
  22.     while(getline(in, line))  
  23.         words.push_back(line);  
  24.   
  25.     in.close();  
  26.   
  27.     vector<string>::const_iterator it = words.cbegin();  
  28.     while (it != words.cend())  
  29.     {  
  30.         cout<< *it <<endl;  
  31.         ++it;  
  32.     }  
  33.     return 0;  
  34. }  

練習8.5:重寫上面的程序,將每個單詞作為一個獨立的元素進行存儲。

 

  1. #include <iostream>  
  2. #include <string>  
  3. #include <fstream>  
  4. #include <vector>  
  5. using std::cout;  
  6. using std::endl;  
  7. using std::string;  
  8. using std::ifstream;  
  9. using std::cerr;  
  10. using std::vector;  
  11.   
  12. int main()  
  13. {  
  14.     ifstream in("data.txt");  
  15.     if(!in) {  
  16.         cerr<<"Can't open the file."<<endl;  
  17.         return -1;  
  18.     }  
  19.   
  20.     string line;  
  21.     vector<string> words;  
  22.     while(in >> line)  
  23.         words.push_back(line);  
  24.   
  25.     in.close();  
  26.   
  27.     vector<string>::const_iterator it = words.cbegin();  
  28.     while (it != words.cend())  
  29.     {  
  30.         cout<< *it <<endl;  
  31.         ++it;  
  32.     }  
  33.     return 0;  
  34. }  

練習8.6:重寫7.1.1節的書店程序,從一個文件中讀取交易記錄。將文件名作為一個參數傳遞給main。

 

  1. #include <iostream>  
  2. #include <fstream>  
  3. #include "Sales_data.h"  
  4.   
  5. using std::cout;  
  6. using std::cerr;  
  7. using std::ifstream;  
  8. using std::endl;  
  9.   
  10. int main(int argc, char *argv[])  
  11. {  
  12.     if (argc != 2) {  
  13.         cerr<< "Please give the file name."<<endl;  
  14.         return -1;  
  15.     }  
  16.     ifstream in(argv[1]);  
  17.     if (!in) {  
  18.         cerr<<"Can't open the file."<<endl;  
  19.         return -1;  
  20.     }  
  21.   
  22.     Sales_data total;  
  23.     if (read(in, total)) {  
  24.         Sales_data trans;  
  25.         while(read(in ,trans)) {  
  26.             if(total.isbn() == trans.isbn())  
  27.                 total.combine(trans);  
  28.             else {  
  29.                 print(cout, total) << endl;  
  30.                 total =trans;  
  31.             }  
  32.         }  
  33.         print(cout, total)<<endl;  
  34.     }  
  35.     else {  
  36.         cerr<<" No data?!"<<endl;  
  37.     }  
  38.     return 0;  
  39. }  

練習8.7:修改上一節的書店程序,將結果保存到一個文件中。將輸出文件名作為第二個參數傳遞給main函數。

 

  1. #include <iostream>  
  2. #include <fstream>  
  3. #include "Sales_data.h"  
  4.   
  5. using std::cerr;  
  6. using std::ifstream;  
  7. using std::ofstream;  
  8. using std::endl;  
  9.   
  10. int main(int argc, char *argv[])  
  11. {  
  12.     if (argc != 3) {  
  13.         cerr<< "Please give the input file name and out file name."<<endl;  
  14.         return -1;  
  15.     }  
  16.     ifstream in(argv[1]);  
  17.     if (!in) {  
  18.         cerr<<"Can't open the file."<<endl;  
  19.         return -1;  
  20.     }  
  21.     ofstream out(argv[2]);  
  22.     if (!out) {  
  23.         cerr<<"can't open output file."<<endl;  
  24.         return -1;  
  25.     }  
  26.   
  27.     Sales_data total;  
  28.     if (read(in, total)) {  
  29.         Sales_data trans;  
  30.         while(read(in ,trans)) {  
  31.             if(total.isbn() == trans.isbn())  
  32.                 total.combine(trans);  
  33.             else {  
  34.                 print(out, total) << endl;  
  35.                 total =trans;  
  36.             }  
  37.         }  
  38.         print(out, total)<<endl;  
  39.     }  
  40.     else {  
  41.         cerr<<" No data?!"<<endl;  
  42.     }  
  43.     return 0;  
  44. }  


練習8.8:修改上一題的程序,將結果追加到給定的文件末尾。對同一個輸出文件,運行程序至少兩次,檢驗數據是否得以保留。

 

  1. #include <iostream>  
  2. #include <fstream>  
  3. #include "Sales_data.h"  
  4.   
  5. using std::cerr;  
  6. using std::ifstream;  
  7. using std::ofstream;  
  8. using std::endl;  
  9.   
  10. int main(int argc, char *argv[])  
  11. {  
  12.     if (argc != 3) {  
  13.         cerr<< "Please give the input file name and out file name."<<endl;  
  14.         return -1;  
  15.     }  
  16.     ifstream in(argv[1]);  
  17.     if (!in) {  
  18.         cerr<<"Can't open the file."<<endl;  
  19.         return -1;  
  20.     }  
  21.     ofstream out(argv[2], ofstream::app);  
  22.     if (!out) {  
  23.         cerr<<"can't open output file."<<endl;  
  24.         return -1;  
  25.     }  
  26.   
  27.     Sales_data total;  
  28.     if (read(in, total)) {  
  29.         Sales_data trans;  
  30.         while(read(in ,trans)) {  
  31.             if(total.isbn() == trans.isbn())  
  32.                 total.combine(trans);  
  33.             else {  
  34.                 print(out, total) << endl;  
  35.                 total =trans;  
  36.             }  
  37.         }  
  38.         print(out, total)<<endl;  
  39.     }  
  40.     else {  
  41.         cerr<<" No data?!"<<endl;  
  42.     }  
  43.     return 0;  
  44. }  

練習8.3.1:使用你為8.1.2節第一個練習所編寫的函數打印一個istringstream對象的內容。

 

  1. #include <iostream>  
  2. #include <sstream>  
  3. #include <string>  
  4. #include <stdexcept>  
  5.   
  6. using std::istream;  
  7. using std::ostringstream;  
  8. using std::istringstream;  
  9. using std::string;  
  10. using std::cout;  
  11. using std::cerr;  
  12. using std::endl;  
  13. using std::runtime_error;  
  14.   
  15. istream &f(istream &in)  
  16. {  
  17.     int v;  
  18.     while(in >> v, !in.eof())  
  19.     {  
  20.         if(in.bad())  
  21.             throw runtime_error("IO Stream error.");  
  22.         if(in.fail())  
  23.         {  
  24.             cerr<<"Data error! Please try again."<<endl;  
  25.             in.clear();  
  26.             in.ignore(100, '\n');  
  27.             continue;  
  28.         }  
  29.         cout<< v <<endl;  
  30.     }  
  31.     in.clear();  
  32.     return in;  
  33. }  
  34.   
  35. int main()  
  36. {  
  37.     ostringstream msg;  
  38.     msg<<"C++ Primer 5th edition"<<endl;  
  39.     istringstream in(msg.str());  
  40.     f(in);  
  41.     return 0;  
  42. }  

練習8.10:編寫程序,將來自一個文件中的行保存在一個vector<string>中。然后使用一個istringstream從vector讀取數據元素,每次讀取一個單詞。
  1. #include <iostream>  
  2. #include <fstream>  
  3. #include <sstream>  
  4. #include <string>  
  5. #include <vector>  
  6.   
  7. using std::cerr;  
  8. using std::endl;  
  9. using std::cout;  
  10. using std::ifstream;  
  11. using std::istringstream;  
  12. using std::string;  
  13. using std::vector;  
  14.   
  15. int main()  
  16. {  
  17.     ifstream in("Data.txt");  
  18.     if (!in) {  
  19.         cerr<<" Can't open input file."<<endl;  
  20.         return -1;  
  21.     }  
  22.   
  23.     string line;  
  24.     vector<string> words;  
  25.     while (getline(in, line)) {  
  26.         words.push_back(line);  
  27.     }  
  28.     in.close();  
  29.   
  30.     vector<string>::const_iterator it = words.begin();  
  31.     while( it != words.end()) {  
  32.         istringstream line_str(*it);  
  33.         string word;  
  34.         while(line_str >> word)  
  35.             cout<< endl;  
  36.         ++it;  
  37.     }  
  38.   
  39.     return 0;  
  40. }  

練習8.11:本節的程序在外層while循環中定義了istringstream對象。如果record對象定義在循環之外,你需要對程序進行怎么樣的修改?重寫程序,將record的定義移到while循環之外,驗證你設想的修改方法是否正確。

 

  1. #include <iostream>  
  2. #include <sstream>  
  3. #include <string>  
  4. #include <vector>  
  5.   
  6. using std::cin;  
  7. using std::istringstream;  
  8. using std::string;  
  9. using std::vector;  
  10.   
  11. struct PersonInfo {  
  12.     string name;  
  13.     vector<string> phones;  
  14. };  
  15.   
  16. int main()  
  17. {  
  18.     string line, word;  
  19.     vector<PersonInfo> people;  
  20.     istringstream record;  
  21.   
  22.     while (getline(cin,line)) {  
  23.         PersonInfo info;  
  24.         record.clear();  
  25.         record.str(line);  
  26.         record >> info.name;  
  27.         while (record >> word)  
  28.             info.phones.push_back(word);  
  29.   
  30.     people.push_back(info);  
  31.     }  
  32.   
  33.     return 0;  
  34. }  

練習8.12:我們為什么沒有在PersonInfo中使用類內初始化?

由於每個人的電話號數量不固定,因此更好的方式不是通過類內初始化指定人名和所有電話號碼,而是在缺省初始化之后,在程序中設置人名並逐個添加電話號碼。


練習8.13:重寫本節的電話號碼程序,從一個命名文件而非cin讀取數據。

 

  1. #include <iostream>  
  2. #include <fstream>  
  3. #include <sstream>  
  4. #include <string>  
  5. #include <vector>  
  6.   
  7. using std::cerr;  
  8. using std::endl;  
  9. using std::cout;  
  10. using std::ifstream;  
  11. using std::istringstream;  
  12. using std::ostringstream;  
  13. using std::string;  
  14. using std::vector;  
  15.   
  16. struct PersonInfo {  
  17.     string name;  
  18.     vector<string> phones;  
  19. };  
  20.   
  21. string format(const string &s) { return s; }  
  22.   
  23. bool valid(const string &s)  
  24. {  
  25.     return true;  
  26. }  
  27.   
  28. int main(int argc, char *argv[])  
  29. {  
  30.     string line, word;  
  31.     vector<PersonInfo> people;  
  32.     istringstream record;  
  33.   
  34.     if (argc != 2) {  
  35.         cerr<<"Please give the file name."<<endl;  
  36.         return -1;  
  37.     }  
  38.     ifstream in(argv[1]);  
  39.     if(!in)  
  40.     {  
  41.         cerr<<"can't open input file"<<endl;  
  42.         return -1;  
  43.     }  
  44.   
  45.     while (getline(in, line)) {  
  46.         PersonInfo info;  
  47.         record.clear();  
  48.         record.str(line);  
  49.         record >> info.name;  
  50.         while(record >> word)  
  51.             info.phones.push_back(word);  
  52.   
  53.         people.push_back(info);  
  54.   
  55.     }  
  56.   
  57.     ostringstream os;  
  58.     for (const auto &entry : people) {  
  59.         ostringstream formatted, badNums;  
  60.         for(const auto &nums : entry.phones) {  
  61.             if (!valid(nums)) {  
  62.                 badNums << " "<< nums;  
  63.             }  
  64.             else  
  65.                 formatted << " " <<format(nums);  
  66.         }  
  67.         if (badNums.str().empty())  
  68.             os <<entry.name<<" "<<formatted.str()<<endl;  
  69.         else  
  70.             cerr<<"input error: "<<entry.name<<" invalid number(s) "<<badNums.str()<<endl;  
  71.     }  
  72.     cout<<os.str()<<endl;  
  73.   
  74.     return 0;  
  75. }  

練習8.14:我們為什么將entry和nums定義為const auto&?

這兩條語句分別適用范圍for語句枚舉people中所有項和每項的phones中的所有項。使用const表明在循環中不會改變這些項的值;auto是請求編譯器依據vector元素類型來推斷出entry和nums的類型,既簡化代碼又避免出錯;使用引用的原因是,people和phones的元素分別是結構對象和字符串對象,使用引用即可避免對象拷貝。

 
 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM