Advertisement
giGii

iostreams beginning

Sep 4th, 2022
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.47 KB | None | 0 0
  1. #include <string>
  2. #include <fstream>
  3. #include <iostream>
  4. #include <iomanip>
  5. #include <vector>
  6.  
  7. using namespace std;
  8.  
  9. void ReadAll(const string& filename) {
  10.  
  11.         ifstream input(filename);
  12.         if (input) {
  13.             string line;
  14.  
  15.             while (getline(input, line)) {
  16.                 cout << line << endl;
  17.             }
  18.         }
  19.  
  20.         input.close();
  21.     }
  22.  
  23. void PrettyPrint(const vector<string>& names, const vector<double>& values, int width=10) {
  24.     for (const auto& n : names) {
  25.         cout << setw(width) << n << ' ';
  26.     }
  27.     cout << endl;
  28.     cout << fixed << setprecision(2);
  29.     for (const auto& v : values) {
  30.         cout << setw(width) << v << ' ';
  31.     }
  32.     cout << endl;
  33. }
  34.  
  35. int main()
  36. {
  37.     // text.txt
  38.     // 1 Hello, World!
  39.     // 2 second line
  40.  
  41.     /* string line;
  42.     ifstream input("text.txt"); // ifstream предназначен для чтения из файлов
  43.     getline(input, line); // getline первым аргументом принимает поток, вторым -- переменную, куда надо записать считанную из потока строку
  44.     cout << line << endl; // Hello, World!
  45.     getline(input, line);
  46.     cout << line << endl; // second line
  47.     getline(input, line);
  48.     cout << line << endl; // second line; здесь и далее снова будет выводиться вторая строка, потому что getline не до конца отрабатывает, и переменная line после последнего считывания не изменяется, и мы выводим одно и то же последнее считанное
  49.     return 0; */
  50.  
  51.     /* string line;
  52.     ifstream input("text.txt"); //  getline возвращает ссылку на поток, из которого она читает данные
  53.     // так как getline возвращает ссылку на поток, а поток, если надо, приводится к типу bool; поэтому можно переписать код так:
  54.     while (getline(input, line)) {
  55.         cout << line << endl;
  56.     }
  57.     return 0; // в итоге выводятся все строчки из файла и ничего лишнего: Hello, World!\nsecond line */
  58.  
  59.     /* string line;
  60.     ifstream input("text.txt");
  61.     while (getline(input, line)) { // getline читает данные до определенного разделителя, которым по умолчанию является перевод строки
  62.         // cout << line << endl; (сам перевод строки не считывается), поэтому переводы каретки нам надо впиливать самостоятельно
  63.         cout << line;
  64.     }
  65.     return 0; // в итоге выводятся все строчки из файла и ничего лишнего, но сами строчки склеены : Hello, World!second line */
  66.  
  67.     /* string line;
  68.     ifstream input1("tetx.txt"); // теперь сдедаем опечатку в имени файла, и программа будет работать! -- это плохо, потому что она не уведомила нас, что ничего не прочитано (ведь файла на самом деле нет)
  69.     while (getline(input1, line)) {
  70.         cout << line;
  71.     }
  72.     cout << "incorrect program is over" << endl << endl;
  73.     input1.close();
  74.  
  75.     // у тех файловых потоков, которые умеют читать данные, есть метод is_open(); он возвращает true, когда файловый поток открыт и готов работать
  76.     ifstream input2("text.txt"); // теперь уберем опечатку в имени файла
  77.     if (input2.is_open()) { // сработает и запись if (input2) {...}, т.к файловый поток приводится к типу bool
  78.         while (getline(input2, line)) {
  79.             cout << line << endl;
  80.         }
  81.         cout << "ok" << endl;
  82.     } else {
  83.         cout << "error" << endl;
  84.     } */
  85.  
  86.     /* // рассмотрим ситуацию, когда нам надо читать из файла не построчно, а выделять какие-то блоки через разделитель
  87.     // date.txt
  88.     // 2022-09-03
  89.  
  90.     ifstream input("date.txt");
  91.  
  92.     if (input) {
  93.         string year;
  94.         string month;
  95.         string day;
  96.         getline(input, year, '-');
  97.         getline(input, month, '-');
  98.         getline(input, day, '-');
  99.  
  100.         cout << year << " " << month << " " << day << " " << endl; // 2022 09 03
  101.  
  102.     } */
  103.  
  104.     /* // читать из потока можно не только с помощью getline, а также с помощью оператора ввода, они же галки >>
  105.     ifstream input("date.txt");
  106.  
  107.     if (input) {
  108.         int year = 0;
  109.         int month = 0;
  110.         int day = 0;
  111.         input >> year; // считываем год, после этого в потоке следующий символ будет -
  112.         input.ignore(1); // у потоков чтения есть метод ignore(), который позволяет пропустить n-ое количество символов в потоке
  113.         input >> month;
  114.         input.ignore(1);
  115.         input >> day;
  116.  
  117.         cout << year << " " << month << " " << day << " " << endl; // 2022 9 3
  118.  
  119.     } */
  120.  
  121.     /* // рассмотрим, как писать данные в файл
  122.  
  123.     const string filename = "output.txt";
  124.     ofstream output(filename);
  125.     output << "hello" << endl;
  126.  
  127.     ifstream input(filename);
  128.     if (input) {
  129.         string line;
  130.  
  131.         while (getline(input, line)) {
  132.             cout << line << endl;
  133.         }
  134.     } */
  135.  
  136.     /* // теперь можно написать функцию, которая примет потоки по ссылке -- см. функцию ReadAll
  137.  
  138.     const string filename = "output.txt";
  139.     ofstream output(filename);
  140.     output << "fine" << endl;
  141.  
  142.     ReadAll(filename); // fine */
  143.  
  144.     /* // но каждый раз, когда мы открываем файл, его содержимое удаляется и запись начинается заново
  145.    
  146.     const string filename = "output.txt";
  147.     ofstream output(filename); // допустим, в файле было слово fine
  148.     output << "world" << endl; // отправим в файл еще одно слово
  149.     ReadAll(filename); // и распечатаем; теперь в файле только слово world  */
  150.  
  151.     /* // но если мы откроем файл в режиме дозаписи в конец
  152.     const string filename = "output.txt";
  153.     ReadAll(filename); // world
  154.     ofstream output(filename, ios::app); // ios::app это режим дозаписи в конец потока
  155.     output << ", world!"; // отправим в файл еще одно слово, endl не пишем, чтобы отправленное и то что было в одной строке оказалось
  156.     output.close(); // обязательно нада закрыть файл после чтения, иначе хоть в файл и дозаписалось, выводиться будет прежнее hello
  157.     ReadAll(filename); // hello, world! */
  158.  
  159.     /* // рассмотрим задачу, когда надо вывести данные в определенном формате
  160.     vector<string> names = {"a", "b", "c"}; // имена колонок, с которыми мы будем работать
  161.     vector<double> values = {5, 0.01, 0.000005}; // значения в колонках
  162.  
  163.     for (const auto& n : names) {
  164.         cout << n << ' ';
  165.     }
  166.     cout << endl;
  167.     for (const auto& v : values) {
  168.         cout << v << ' ';
  169.     } */
  170.  
  171.     /*
  172.     a b c
  173.     5 0.01 5e-06
  174.      */
  175.  
  176.     /* вывод трудночитаемый; чтобы решить такую задачу в языке С++ есть потоковые манипуляторы
  177.     это манипуляторы, которые, работая с потоком, как-то изменяют его поведение */
  178.  
  179.     /* для начала сделаем так, чтобы число выводилось не в экспоненциальном формате, а с десятичной точкой
  180.     для этого надо написать cout << fixed, и с этого момента вывод в поток будет с десятичной точкой
  181.     также надо подключить заголовок #include <iomanip> */
  182.    
  183.    
  184.     /* vector<string> names = {"a", "b", "c"};
  185.     vector<double> values = {5, 0.01, 0.000005};
  186.    
  187.     for (const auto& n : names) {
  188.         cout << n << ' ';
  189.     }
  190.     cout << endl;
  191.     cout << fixed;
  192.     for (const auto& v : values) {
  193.         cout << v << ' ';
  194.     } */
  195.    
  196.     /*
  197.     a b c
  198.     5.000000 0.010000 0.000005
  199.      */
  200.    
  201.     // теперь числа не в экспоненциальной форме, но точность слишком высока; введем еще один манипулятор cout << setprecision(2)
  202.    
  203.     /* vector<string> names = {"a", "b", "c"};
  204.     vector<double> values = {5, 0.01, 0.000005};
  205.  
  206.     for (const auto& n : names) {
  207.         cout << n << ' ';
  208.     }
  209.     cout << endl;
  210.     cout << fixed << setprecision(2);
  211.     for (const auto& v : values) {
  212.         cout << v << ' ';
  213.     } */
  214.    
  215.     /*
  216.     a b c
  217.     5.00 0.01 0.00
  218.      */
  219.    
  220.     /* теперь числа не такие длинные, но читать все равно еще неудобно; зарезервируем в строке несколько
  221.     символов под следующий вывод установкой манипулятора cout << setw(10) */
  222.  
  223.     /* vector<string> names = {"a", "b", "c"};
  224.     vector<double> values = {5, 0.01, 0.000005};
  225.    
  226.     for (const auto& n : names) {
  227.         cout << n << ' ';
  228.     }
  229.     cout << endl;
  230.     cout << fixed << setprecision(2) << setw(10);
  231.     for (const auto& v : values) {
  232.         cout << v << ' ';
  233.     } */
  234.    
  235.     /*
  236.     a b c
  237.           5.00 0.01 0.00
  238.      */
  239.  
  240.     /* ключевой особенностью манипулятора setw является то, что он сбрасывается после первого вывода
  241.     поэтому его надо устанавливать каждый раз, когда надо что-то вывести */
  242.  
  243.     /* vector<string> names = {"a", "b", "c"};
  244.     vector<double> values = {5, 0.01, 0.000005};
  245.    
  246.     for (const auto& n : names) {
  247.         cout << setw(10) << n << ' ';
  248.     }
  249.     cout << endl;
  250.     cout << fixed << setprecision(2);
  251.     for (const auto& v : values) {
  252.         cout << setw(10) << v << ' ';
  253.     } */
  254.  
  255.     /*
  256.              a          b          c
  257.           5.00       0.01       0.00
  258.      */
  259.  
  260.     // напишем функцию PrettyPrint, которая будет принимать вектор имен колонок и вектор значений и красиво печатать их
  261.    
  262.     /* vector<string> names = {"a", "b", "c"};
  263.     vector<double> values = {5, 0.01, 0.000005};
  264.     PrettyPrint(names, values); */
  265.  
  266.     /*
  267.              a          b          c
  268.           5.00       0.01       0.00
  269.      */
  270.  
  271.     // чтобы заполнить пустое пространство другим заполнителем, можно передать манипулятор setfill
  272.  
  273.     /* cout << setfill('.');
  274.  
  275.     vector<string> names = {"a", "b", "c"};
  276.     vector<double> values = {5, 0.01, 0.000005};
  277.  
  278.     PrettyPrint(names, values, 15); */
  279.  
  280.     /*
  281.     ..............a..............b..............c
  282.     ...........5.00...........0.01...........0.00
  283.      */
  284.  
  285.     // также иногда бывает полезно выводить числа не справа, а слева, и для этого есть манипулятор left
  286.    
  287.     /* cout << left << setfill('.');
  288.  
  289.     vector<string> names = {"a", "b", "c"};
  290.     vector<double> values = {5, 0.01, 0.000005};
  291.  
  292.     PrettyPrint(names, values, 15); */
  293.  
  294.     /*
  295.     a.............. b.............. c..............
  296.     5.00........... 0.01........... 0.00...........
  297.      */
  298.  
  299.     return 0;
  300. }
  301.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement