2. C++ Avancé




2.1. Les flux

Les flux permettent la lecture ou l'écriture d'information. A la différence du C on utilise pas un format d'affichage mais les informations sont envoyées de manière sérielle.

2.1.1. Les flux standard et les opérateurs d'indirection

on utilise les opérateurs de redirection :

2.1.2. Ecriture

On dispose d'un ensemble de manipulateurs qui autorisent la modification dont l'information est affichée :

  1. #include <iostream>
  2. #include <iomanip>
  3. #include <vector>
  4. using namespace std;
  5.  
  6. vector<vector<double>> matrix;
  7. const int MAX_ROWS = 4;
  8. const int MAX_COLS = 3;
  9.  
  10. int main() {
  11.     for (int i=0; i<MAX_ROWS; ++i) {
  12.         matrix.push_back(vector<double>(MAX_COLS));
  13.     }
  14.     for (int i=0; i<MAX_ROWS; ++i) {
  15.         for (int j=0; j<MAX_COLS; ++j) {
  16.             if ((j % 2)==0) {
  17.                 matrix[i][j] = static_cast<double>(1.0)/(2.0+i+j);
  18.             } else {
  19.                 matrix[i][j] = static_cast<double>(rand())/(2.0+i+j);
  20.             }
  21.         }
  22.     }
  23.    
  24.     // print line of 40 '='
  25.     cout << setw(40) << setfill('=') << '\0' << endl;
  26.    
  27.    
  28.     vector<vector<double>>::iterator row_it;
  29.     vector<double>::iterator col_it;
  30.    
  31.     // =============================================
  32.     // print matrix contents in three different ways
  33.     // =============================================
  34.    
  35.    
  36.     // 1. default
  37.     cout << "default ===========" << endl;
  38.     cout.precision(8);
  39.     for (row_it = matrix.begin(); row_it != matrix.end(); ++row_it) {
  40.         for (col_it = (*row_it).begin(); col_it != (*row_it).end(); ++col_it) {
  41.             cout << setw(20);  
  42.             cout << *(col_it);
  43.            
  44.         }
  45.         cout << endl;
  46.     }  
  47.     cout << endl;
  48.    
  49.     // 2. scientific
  50.     cout << "scientific ===========" << endl;
  51.     cout << std::scientific;
  52.     cout.precision(8);
  53.     for (row_it = matrix.begin(); row_it != matrix.end(); ++row_it) {
  54.         for (col_it = (*row_it).begin(); col_it != (*row_it).end(); ++col_it) {
  55.             cout << setw(20);  
  56.             cout << *(col_it);
  57.            
  58.         }
  59.         cout << endl;
  60.     }  
  61.     cout << endl;
  62.    
  63.     // 3. fixed
  64.     cout << "fixed ===========" << endl;
  65.     cout << std::fixed;
  66.     cout.precision(8);
  67.     cout << setfill('_');
  68.     for (row_it = matrix.begin(); row_it != matrix.end(); ++row_it) {
  69.         for (col_it = (*row_it).begin(); col_it != (*row_it).end(); ++col_it) {
  70.             cout << setw(20);  
  71.             cout << *(col_it);
  72.            
  73.         }
  74.         cout << endl;
  75.     }  
  76.    
  77.     return 0;
  78. }
  79.  
  80.  
123456789012345678901234567890123456789012345678901234567890
default ===========
                 0.5       6.0142979e+08                0.25
          0.33333333       2.1173272e+08                 0.2
                0.25       3.3633856e+08          0.16666667
                 0.2       2.8577282e+08          0.14285714

scientific ===========
      5.00000000e-01      6.01429794e+08      2.50000000e-01
      3.33333333e-01      2.11732722e+08      2.00000000e-01
      2.50000000e-01      3.36338555e+08      1.66666667e-01
      2.00000000e-01      2.85772819e+08      1.42857143e-01

fixed ===========
__________0.50000000__601429794.33333337__________0.25000000
__________0.33333333__211732721.50000000__________0.20000000
__________0.25000000__336338555.39999998__________0.16666667
__________0.20000000__285772819.16666669__________0.14285714

2.1.3. Lecture

Lecture depuis le clavier : utiliser Ctrl-D pour fermer le flux ou utiliser un pipe

  1. #include <iostream>
  2. #include <istream>
  3. #include <vector>
  4. #include <iterator>
  5. #include <string>
  6. #include <algorithm>
  7. #include <functional>
  8. #include <cstdlib>
  9. using namespace std;
  10.  
  11.  
  12. int main() {
  13.    
  14.     istream_iterator<string> cin_iter(std::cin);
  15.     istream_iterator<string> cin_end;
  16.    
  17.     vector<string> v;
  18.     for ( ; cin_iter != cin_end; ++cin_iter) {
  19.         v.push_back(*cin_iter);
  20.     }
  21.     copy(v.begin(), v.end(), ostream_iterator<string>(cout, " * "));
  22.     cout << endl;  
  23.     return EXIT_SUCCESS;
  24. }
  25.  
  26.  
\$ ./c2_stream_cin_read.exe 
abc def, ghi jkl^D
abc * def, * ghi * jkl *
 
\$ echo "ab cd ef,gh ij" | ./c2_stream_cin_read.exe 
ab * cd * ef,gh * ij * 

2.1.4. Les fichiers : fstream

La classe fstream permet de gérer les fichiers en lecture ou en écriture.

On utilise les méthodes open pour ouvrir le fichier et close pour le fermer.

  1. #include <iostream>
  2. #include <fstream>
  3. #include <stdexcept>
  4. using namespace std;
  5.  
  6. int main() {
  7.     fstream file;
  8.    
  9.     const char *file_name = "data.txt";
  10.    
  11.     // ===================================
  12.     // create file
  13.     // ===================================
  14.     file.open(file_name, ios::out);
  15.     if (!file.is_open()) {
  16.         throw runtime_error("could not open file");
  17.     }
  18.    
  19.     const int ROWS = 5;
  20.     const int COLS = 4;
  21.    
  22.     file << ROWS << " " << COLS << endl;
  23.     for (int i=0; i<ROWS; ++i) {
  24.         file << "line" << i << " ";
  25.         for (int j=0; j<COLS; ++j) {
  26.             file << 20*i+j << " ";
  27.         }
  28.         file << endl;
  29.     }
  30.    
  31.     file.close();
  32.    
  33.     // ===================================
  34.     // read file by tokens
  35.     // ===================================
  36.     file.open(file_name, ios::in);
  37.     if (!file.is_open()) {
  38.         throw runtime_error("could not open file");
  39.     }
  40.    
  41.     int rows, cols, value;
  42.     string str;
  43.    
  44.     file >> rows >> cols;
  45.     for (int i=0; i<rows; ++i) {
  46.         file >> str;
  47.         for (int j=0; j<cols; ++j) {
  48.             file >> value;
  49.             cout << "read: " << str << " " << value << endl;
  50.         }
  51.     }
  52.    
  53.     file.close();
  54.    
  55.     // ===================================
  56.     // read file by lines
  57.     // ===================================
  58.     file.open(file_name, ios::in);
  59.     if (!file.is_open()) {
  60.         throw runtime_error("could not open file");
  61.     }
  62.    
  63.     string line;
  64.        
  65.     file >> rows >> cols;
  66.     for (int i=0; i<rows; ++i) {
  67.         getline(file, line);
  68.         cout << "[" << line << "]" << endl;
  69.     }
  70.    
  71.     file.close();
  72.     return 0;
  73. }
  74.  
read: line0 0
read: line0 1
read: line0 2
read: line0 3
read: line1 20
...
read: line4 83
lecture ligne à ligne : attention ligne vide après 5 4 \n
[]
[line0 0 1 2 3 ]
[line1 20 21 22 23 ]
[line2 40 41 42 43 ]
[line3 60 61 62 63 ]

Le fichier écrit puis relu est le suivant :

5 4  <--- 5 lignes, 4 colonnes
line0 0 1 2 3 
line1 20 21 22 23 
line2 40 41 42 43 
line3 60 61 62 63 
line4 80 81 82 83

2.1.5. Les chaines comme flux : sstream

  1. #include <iostream>
  2. #include <sstream>
  3. #include <stdexcept>
  4. #include <vector>
  5. #include <string>
  6. #include <cstdlib>
  7. using namespace std;
  8.  
  9. /**
  10.  * main function
  11.  */
  12. int main() {
  13.     string word;
  14.     vector<string> words;
  15.    
  16.     // ==========================================
  17.     // read string from keyboard
  18.     // terminate input with ^D
  19.     // ==========================================
  20.    
  21.     // read words and put them into a vector
  22.     while (cin >> word) {
  23.         words.push_back(word);
  24.     }
  25.    
  26.     // display what was read from keyboard
  27.     ostringstream oss;
  28.     for (int i=0; i<words.size(); ++i) {
  29.         oss << i << ": " << words[i] << endl;
  30.     }
  31.     cout << oss.str() << endl;
  32.    
  33.     // ==========================================
  34.     // use of istringstream
  35.     // distinguish between strings and numbers
  36.     // ==========================================
  37.    
  38.     string str = "  exemple 2 phrase à  étudier 123  ";
  39.     istringstream iss(str);
  40.     int n = 1;
  41.     while (iss >> word) {
  42.         if (isdigit(word[0])) {
  43.             cout << "number : " << atoi(word.c_str()) << endl;
  44.         } else {
  45.             cout << n << ": " << word << endl;
  46.         }
  47.         ++n;
  48.     }  
  49.     return 0;
  50. }
  51.  
12.5 abc def 0 @CTRL-D
0: 12.5
1: abc
2: def
3: 0
4: @

1: exemple
number: 2
3: phrase
4: à
5: étudier
number: 123