С++: читаем текстовый файл в вектор строк
Немного познакомившись с векторами и поточными классами, это легко сделать.
Предположив, что юникод-файл с именем data.txt
расположен в текущей папке консольного проекта,
прочитаем его строки в вектор из элементов string
, а затем выведем в консоль общее количество строк и символов в файле.
Обратите внимание, что если в конце файла есть "лишний" перевод строки, на которую можно поставить курсор, но она не содержит ни одного символа, отдельной строкой такая позиция считаться не будет:
Здесь Три Строки |
Также стоит посмотреть, как находится сумма длин строк стандартным методом accumulate
из библиотеки
<numeric>
, содержащий "заготовки" для реализации типовых алгоритмов. При этом для Юникода посчитается именно "общее количество байт, отведённое под все символы", исключая "двойной" для Windows символ CR/LF (\r\n
, возврат каретки и перевод строки). Для приведённого выше теста получим:
3 string(s) 28 chars(s) without endl
при размере юникод-файла 34 байта.
"|" в последней строке тестового файла - не символ, а обозначение положения курсора при наличии CR/LF после слова "Строки".
Если последняя строка не завершается CR/LF и файл имеет размер 32 байта, ответы всё равно не изменятся :)
#include <cstdlib> #include <iostream> #include <fstream> #include <string> #include <vector> #include <numeric> /*библиотека для стандартных алгоритмов сумма, произведение и т.п.*/ using namespace std; void error (string message,int errorcode) { cout << endl << message; system("pause>nul"); exit(errorcode); } int main() { string line; vector <string> v; ifstream file("data.txt"); /*файл - в Юникоде (utf-8)*/ if (!file) { error(string("Error opening input file"),1); } while (getline(file, line)) { v.push_back(line); } cout << endl << v.size() << " string(s)"; int chars = accumulate(v.begin(), v.end(), 0, [](int sum, const string &item) { return sum + item.size(); }); cout << endl << chars << " chars(s) without endl"; system("pause>nul"); return 0; }
В принципе, при построчном чтении файла в вектор строк, основной цикл обработки можно было организовать и так:
do { file >> line; v.push_back(line); } while (!file.eof());
При посимвольном чтении из файла решение будет примерно таким:
/* Пример С++ для посимвольного считывания текста из многострочного текстового файла с запоминанием каждого абзаца внутри вектора */ #include <fstream> //Для файловых потоков #include <iostream> #include <string> //Для контейнера string #include <vector> //Для контейнера vector #include <iterator> //Для вывода элементов вектора на экран с помощью алгоритма copy #include <string> #include <windows.h> using namespace std; int main() { setlocale(LC_ALL, "RUS"); SetConsoleCP(1251); SetConsoleOutputCP(1251); int ch = 0; //Это переменная, в которую нужно считывать символы string s; //Это строка, она в примере будет абзацем vector<string> v; //Вектор строк const char *filename = "data.txt"; //Считаем текст с форматированием ifstream file(filename); //открыли для чтения файл while ((ch = file.get()) != EOF) { if (char(ch) != '\n') s = s + char(ch); //Считываем символ из файла и сразу проверяем его на признак переноса строки. else { v.push_back(s); //Если текущий символ перенос, то записываем строку в вектор s.clear(); //Очищаем строку } } v.push_back(s); //Дописываем последнюю строку в вектор file.close(); copy(v.begin(), v.end(), std::ostream_iterator<string>(cout, "\n")); //Вывожу вектор на экран cin.get(); return 0; }
03.05.2017, 11:19 [8870 просмотров]