Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <string>
- #include <fstream>
- #include <iostream>
- #include <iomanip>
- #include <vector>
- using namespace std;
- void ReadAll(const string& filename) {
- ifstream input(filename);
- if (input) {
- string line;
- while (getline(input, line)) {
- cout << line << endl;
- }
- }
- input.close();
- }
- void PrettyPrint(const vector<string>& names, const vector<double>& values, int width=10) {
- for (const auto& n : names) {
- cout << setw(width) << n << ' ';
- }
- cout << endl;
- cout << fixed << setprecision(2);
- for (const auto& v : values) {
- cout << setw(width) << v << ' ';
- }
- cout << endl;
- }
- int main()
- {
- // text.txt
- // 1 Hello, World!
- // 2 second line
- /* string line;
- ifstream input("text.txt"); // ifstream предназначен для чтения из файлов
- getline(input, line); // getline первым аргументом принимает поток, вторым -- переменную, куда надо записать считанную из потока строку
- cout << line << endl; // Hello, World!
- getline(input, line);
- cout << line << endl; // second line
- getline(input, line);
- cout << line << endl; // second line; здесь и далее снова будет выводиться вторая строка, потому что getline не до конца отрабатывает, и переменная line после последнего считывания не изменяется, и мы выводим одно и то же последнее считанное
- return 0; */
- /* string line;
- ifstream input("text.txt"); // getline возвращает ссылку на поток, из которого она читает данные
- // так как getline возвращает ссылку на поток, а поток, если надо, приводится к типу bool; поэтому можно переписать код так:
- while (getline(input, line)) {
- cout << line << endl;
- }
- return 0; // в итоге выводятся все строчки из файла и ничего лишнего: Hello, World!\nsecond line */
- /* string line;
- ifstream input("text.txt");
- while (getline(input, line)) { // getline читает данные до определенного разделителя, которым по умолчанию является перевод строки
- // cout << line << endl; (сам перевод строки не считывается), поэтому переводы каретки нам надо впиливать самостоятельно
- cout << line;
- }
- return 0; // в итоге выводятся все строчки из файла и ничего лишнего, но сами строчки склеены : Hello, World!second line */
- /* string line;
- ifstream input1("tetx.txt"); // теперь сдедаем опечатку в имени файла, и программа будет работать! -- это плохо, потому что она не уведомила нас, что ничего не прочитано (ведь файла на самом деле нет)
- while (getline(input1, line)) {
- cout << line;
- }
- cout << "incorrect program is over" << endl << endl;
- input1.close();
- // у тех файловых потоков, которые умеют читать данные, есть метод is_open(); он возвращает true, когда файловый поток открыт и готов работать
- ifstream input2("text.txt"); // теперь уберем опечатку в имени файла
- if (input2.is_open()) { // сработает и запись if (input2) {...}, т.к файловый поток приводится к типу bool
- while (getline(input2, line)) {
- cout << line << endl;
- }
- cout << "ok" << endl;
- } else {
- cout << "error" << endl;
- } */
- /* // рассмотрим ситуацию, когда нам надо читать из файла не построчно, а выделять какие-то блоки через разделитель
- // date.txt
- // 2022-09-03
- ifstream input("date.txt");
- if (input) {
- string year;
- string month;
- string day;
- getline(input, year, '-');
- getline(input, month, '-');
- getline(input, day, '-');
- cout << year << " " << month << " " << day << " " << endl; // 2022 09 03
- } */
- /* // читать из потока можно не только с помощью getline, а также с помощью оператора ввода, они же галки >>
- ifstream input("date.txt");
- if (input) {
- int year = 0;
- int month = 0;
- int day = 0;
- input >> year; // считываем год, после этого в потоке следующий символ будет -
- input.ignore(1); // у потоков чтения есть метод ignore(), который позволяет пропустить n-ое количество символов в потоке
- input >> month;
- input.ignore(1);
- input >> day;
- cout << year << " " << month << " " << day << " " << endl; // 2022 9 3
- } */
- /* // рассмотрим, как писать данные в файл
- const string filename = "output.txt";
- ofstream output(filename);
- output << "hello" << endl;
- ifstream input(filename);
- if (input) {
- string line;
- while (getline(input, line)) {
- cout << line << endl;
- }
- } */
- /* // теперь можно написать функцию, которая примет потоки по ссылке -- см. функцию ReadAll
- const string filename = "output.txt";
- ofstream output(filename);
- output << "fine" << endl;
- ReadAll(filename); // fine */
- /* // но каждый раз, когда мы открываем файл, его содержимое удаляется и запись начинается заново
- const string filename = "output.txt";
- ofstream output(filename); // допустим, в файле было слово fine
- output << "world" << endl; // отправим в файл еще одно слово
- ReadAll(filename); // и распечатаем; теперь в файле только слово world */
- /* // но если мы откроем файл в режиме дозаписи в конец
- const string filename = "output.txt";
- ReadAll(filename); // world
- ofstream output(filename, ios::app); // ios::app это режим дозаписи в конец потока
- output << ", world!"; // отправим в файл еще одно слово, endl не пишем, чтобы отправленное и то что было в одной строке оказалось
- output.close(); // обязательно нада закрыть файл после чтения, иначе хоть в файл и дозаписалось, выводиться будет прежнее hello
- ReadAll(filename); // hello, world! */
- /* // рассмотрим задачу, когда надо вывести данные в определенном формате
- vector<string> names = {"a", "b", "c"}; // имена колонок, с которыми мы будем работать
- vector<double> values = {5, 0.01, 0.000005}; // значения в колонках
- for (const auto& n : names) {
- cout << n << ' ';
- }
- cout << endl;
- for (const auto& v : values) {
- cout << v << ' ';
- } */
- /*
- a b c
- 5 0.01 5e-06
- */
- /* вывод трудночитаемый; чтобы решить такую задачу в языке С++ есть потоковые манипуляторы
- это манипуляторы, которые, работая с потоком, как-то изменяют его поведение */
- /* для начала сделаем так, чтобы число выводилось не в экспоненциальном формате, а с десятичной точкой
- для этого надо написать cout << fixed, и с этого момента вывод в поток будет с десятичной точкой
- также надо подключить заголовок #include <iomanip> */
- /* vector<string> names = {"a", "b", "c"};
- vector<double> values = {5, 0.01, 0.000005};
- for (const auto& n : names) {
- cout << n << ' ';
- }
- cout << endl;
- cout << fixed;
- for (const auto& v : values) {
- cout << v << ' ';
- } */
- /*
- a b c
- 5.000000 0.010000 0.000005
- */
- // теперь числа не в экспоненциальной форме, но точность слишком высока; введем еще один манипулятор cout << setprecision(2)
- /* vector<string> names = {"a", "b", "c"};
- vector<double> values = {5, 0.01, 0.000005};
- for (const auto& n : names) {
- cout << n << ' ';
- }
- cout << endl;
- cout << fixed << setprecision(2);
- for (const auto& v : values) {
- cout << v << ' ';
- } */
- /*
- a b c
- 5.00 0.01 0.00
- */
- /* теперь числа не такие длинные, но читать все равно еще неудобно; зарезервируем в строке несколько
- символов под следующий вывод установкой манипулятора cout << setw(10) */
- /* vector<string> names = {"a", "b", "c"};
- vector<double> values = {5, 0.01, 0.000005};
- for (const auto& n : names) {
- cout << n << ' ';
- }
- cout << endl;
- cout << fixed << setprecision(2) << setw(10);
- for (const auto& v : values) {
- cout << v << ' ';
- } */
- /*
- a b c
- 5.00 0.01 0.00
- */
- /* ключевой особенностью манипулятора setw является то, что он сбрасывается после первого вывода
- поэтому его надо устанавливать каждый раз, когда надо что-то вывести */
- /* vector<string> names = {"a", "b", "c"};
- vector<double> values = {5, 0.01, 0.000005};
- for (const auto& n : names) {
- cout << setw(10) << n << ' ';
- }
- cout << endl;
- cout << fixed << setprecision(2);
- for (const auto& v : values) {
- cout << setw(10) << v << ' ';
- } */
- /*
- a b c
- 5.00 0.01 0.00
- */
- // напишем функцию PrettyPrint, которая будет принимать вектор имен колонок и вектор значений и красиво печатать их
- /* vector<string> names = {"a", "b", "c"};
- vector<double> values = {5, 0.01, 0.000005};
- PrettyPrint(names, values); */
- /*
- a b c
- 5.00 0.01 0.00
- */
- // чтобы заполнить пустое пространство другим заполнителем, можно передать манипулятор setfill
- /* cout << setfill('.');
- vector<string> names = {"a", "b", "c"};
- vector<double> values = {5, 0.01, 0.000005};
- PrettyPrint(names, values, 15); */
- /*
- ..............a..............b..............c
- ...........5.00...........0.01...........0.00
- */
- // также иногда бывает полезно выводить числа не справа, а слева, и для этого есть манипулятор left
- /* cout << left << setfill('.');
- vector<string> names = {"a", "b", "c"};
- vector<double> values = {5, 0.01, 0.000005};
- PrettyPrint(names, values, 15); */
- /*
- a.............. b.............. c..............
- 5.00........... 0.01........... 0.00...........
- */
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement