C ++-файл ввода-вывода выполняется через потоки . Ключевыми абстракциями являются:
std::istream для чтения текста.
std::ostream для std::ostream текста.
std::streambuf для чтения или записи символов.
В форматированном вводе используется operator>> .
Форматированный вывод использует operator
В потоках используется std::locale , например, для подробностей форматирования и для перевода между внешними кодировками и внутренней кодировкой.
Открытие файла
Открытие файла выполняется одинаково для всех 3 потоков файлов ( ifstream , ofstream и fstream ).
Вы можете открыть файл непосредственно в конструкторе:
std::ifstream ifs(«foo.txt»); // ifstream: Opens file «foo.txt» for reading only. std::ofstream ofs(«foo.txt»); // ofstream: Opens file «foo.txt» for writing only. std::fstream iofs(«foo.txt»); // fstream: Opens file «foo.txt» for reading and writing.
Кроме того, вы можете использовать функцию члена потока файлов open() :
Работа с файлами в Python. Создание, чтение, запись, удаление. Конструкция WITH-AS | Базовый курс
std::ifstream ifs; ifs.open(«bar.txt»); // ifstream: Opens file «bar.txt» for reading only. std::ofstream ofs; ofs.open(«bar.txt»); // ofstream: Opens file «bar.txt» for writing only. std::fstream iofs; iofs.open(«bar.txt»); // fstream: Opens file «bar.txt» for reading and writing.
Вы всегда должны проверить, был ли файл успешно открыт (даже при написании). Ошибки могут включать: файл не существует, файл не имеет прав доступа, файл уже используется, произошли ошибки диска, отключен диск . Проверка может быть выполнена следующим образом:
// Try to read the file ‘foo.txt’. std::ifstream ifs(«fooo.txt»); // Note the typo; the file can’t be opened. // Check if the file has been opened successfully. if (!ifs.is_open()) < // The file hasn’t been opened; take appropriate actions here. throw CustomException(ifs, «File could not be opened»); >
Когда путь к файлу содержит обратную косую черту (например, в системе Windows), вы должны правильно их избежать:
// Open the file ‘c:folderfoo.txt’ on Windows. std::ifstream ifs(«c:\folder\foo.txt»); // using escaped backslashes
или использовать исходный литерал:
// Open the file ‘c:folderfoo.txt’ on Windows. std::ifstream ifs(R»(c:folderfoo.txt)»); // using raw literal
или вместо этого используйте косые черты:
// Open the file ‘c:folderfoo.txt’ on Windows. std::ifstream ifs(«c:/folder/foo.txt»);
Разделение близнец.
Please enable JavaScript
Если вы хотите открыть файл с не-ASCII-символами в пути в Windows, в настоящее время вы можете использовать нестандартный аргумент пути к широкому символу:
// Open the file ‘примерfoo.txt’ on Windows. std::ifstream ifs(LR»(примерfoo.txt)»); // using wide characters with raw literal
Чтение из файла
Существует несколько способов чтения данных из файла.
Работа с файлами в Python. Чтение и запись данных
Если вы знаете, как форматируются данные, вы можете использовать оператор извлечения потока ( >> ). Предположим, у вас есть файл с именем foo.txt, который содержит следующие данные:
John Doe 25 4 6 1987 Jane Doe 15 5 24 1976
Затем вы можете использовать следующий код для чтения этих данных из файла:
// Define variables. std::ifstream is(«foo.txt»); std::string firstname, lastname; int age, bmonth, bday, byear; // Extract firstname, lastname, age, bday month, bday day, and bday year in that order. // Note: ‘>>’ returns false if it reached EOF (end of file) or if the input data doesn’t // correspond to the type of the input variable (for example, the string «foo» can’t be // extracted into an ‘int’ variable). while (is >> firstname >> lastname >> age >> bmonth >> bday >> byear) // Process the data that has been read.
Оператор извлечения потока >> извлекает каждый символ и останавливается, если он находит символ, который нельзя сохранить, или если он является особым символом:
- Для типов строк оператор останавливается в пробеле ( ) или в новой строке ( n ).
- Для чисел оператор останавливается с символом, отличным от числа.
Это означает, что следующая версия файла foo.txt также будет успешно прочитана предыдущим кодом:
John Doe 25 4 6 1987 Jane Doe 15 5 24 1976
Оператор извлечения потока >> всегда возвращает переданный ему поток. Поэтому несколько операторов могут быть соединены друг с другом, чтобы читать данные последовательно. Тем не менее, поток также может быть использован в качестве логического выражения (как показано в while петли в предыдущем коде).
Это связано с тем, что классы потоков имеют оператор преобразования для типа bool . Этот оператор bool() вернет true пока поток не имеет ошибок. Если поток переходит в состояние ошибки (например, поскольку больше не может быть извлечено данных), то оператор bool() вернет false . Таким образом, в while цикл в предыдущем коде будет после того, как вышел из входного файла был прочитан до конца.
Если вы хотите прочитать весь файл в виде строки, вы можете использовать следующий код:
// Opens ‘foo.txt’. std::ifstream is(«foo.txt»); std::string whole_file; // Sets position to the end of the file. is.seekg(0, std::ios::end); // Reserves memory for the file. whole_file.reserve(is.tellg()); // Sets position to the start of the file. is.seekg(0, std::ios::beg); // Sets contents of ‘whole_file’ to all characters in the file. whole_file.assign(std::istreambuf_iterator(is), std::istreambuf_iterator());
Этот код резервирует пространство для string , чтобы сократить ненужные распределения памяти.
Если вы хотите прочитать файл по строкам, вы можете использовать функцию getline() :
std::ifstream is(«foo.txt»); // The function getline returns false if there are no more lines. for (std::string str; std::getline(is, str);) < // Process the line that has been read. >
Если вы хотите прочитать фиксированное количество символов, вы можете использовать функцию члена потока read() :
std::ifstream is(«foo.txt»); char str[4]; // Read 4 characters from the file. is.read(str, 4);
После выполнения команды чтения, вы всегда должны проверить , если состояние ошибки флаг failbit был установлен, поскольку он указывает на то удалось ли операция или нет. Это можно сделать, вызвав функцию члена файлового потока fail() :
is.read(str, 4); // This operation might fail for any reason. if (is.fail()) // Failed to read!
Запись в файл
Существует несколько способов записи в файл. Самый простой способ — использовать поток выходных файлов ( ofstream ) вместе с оператором вставки потока (
std::ofstream os(«foo.txt»); if(os.is_open())
std::ofstream os(«foo.txt»); if(os.is_open()) < char data[] = «Foo»; // Writes 3 characters from data ->»Foo». os.write(data, 3); >
После записи в поток, вы всегда должны проверить , если состояние ошибки флаг badbit был установлен, поскольку он указывает на то удалось ли операция или нет. Это можно сделать, вызвав функцию члена потока выходного файла bad() :
Режимы открытия
При создании потока файлов вы можете указать режим открытия. Режим открытия — это, в основном, параметр для управления тем, как поток открывает файл.
(Все режимы можно найти в пространстве имен std::ios .)
Режим открытия может быть предоставлен в качестве второго параметра конструктору файлового потока или его функции open() :
std::ofstream os(«foo.txt», std::ios::out | std::ios::trunc); std::ifstream is; is.open(«foo.txt», std::ios::in | std::ios::binary);
Следует отметить, что вам нужно установить ios::in или ios::out если вы хотите установить другие флаги, поскольку они неявно устанавливаются членами iostream, хотя они имеют правильное значение по умолчанию.
Если вы не укажете режим открытия, используются следующие режимы по умолчанию:
- ifstream — in
- ofstream — out
- fstream — in и out
Режимы открытия файла, которые вы можете указать по дизайну:
app | присоединять | Выход | Добавляет данные в конец файла. |
binary | двоичный | Ввод, вывод | Вход и выход выполняются в двоичном формате. |
in | вход | вход | Открывает файл для чтения. |
out | выход | Выход | Открывает файл для записи. |
trunc | усекать | Ввод, вывод | Удаляет содержимое файла при открытии. |
ate | в конце | вход | Открывается до конца файла. |
Примечание. Установка binary режима позволяет считывать / записывать данные в точности как есть; не устанавливая его, это позволяет переносить символ новой строки ‘n’ / на определенный конец строки последовательности.
Например, в Windows конец строки — CRLF ( «rn» ).
Напишите: «n» => «rn»
Читайте: «rn» => «n»
Закрытие файла
Явное закрытие файла редко необходимо в C ++, так как поток файлов автоматически закрывает связанный файл в своем деструкторе. Тем не менее, вы должны попытаться ограничить время жизни объекта потока файлов, чтобы он не закрывал дескриптор файла дольше, чем необходимо. Например, это можно сделать, поместив все операции с файлами в собственную область ( <> ):
std::string const prepared_data = prepare_data(); < // Open a file for writing. std::ofstream output(«foo.txt»); // Write data. output // The ofstream will go out of scope here. // Its destructor will take care of closing the file properly.
Вызов close() явно необходимо , только если вы хотите использовать один и тот же fstream объект позже, но не хотите , чтобы сохранить файл открыть между ними:
// Open the file «foo.txt» for the first time. std::ofstream output(«foo.txt»); // Get some data to write from somewhere. std::string const prepared_data = prepare_data(); // Write data to the file «foo.txt». output
Промывка потока
Потоки файлов по умолчанию буферизуются, как и многие другие типы потоков. Это означает, что запись в поток не может привести к немедленному изменению базового файла. Чтобы заставить все буферизованные записи совершать сразу, вы можете очистить поток. Вы можете сделать это напрямую, вызывая метод flush() или с помощью манипулятора std::flush stream:
std::ofstream os(«foo.txt»); os
Существует поток манипулятор std::endl который объединяет запись новой строки с потоком потока:
// Both following lines do the same thing os
Буферизация может улучшить производительность записи в поток. Поэтому приложения, выполняющие много писем, должны избегать излишней очистки. Напротив, если операции ввода-вывода выполняются нечасто, приложения должны часто промывать, чтобы избежать застревания данных в объекте потока.
Чтение файла ASCII в строку std ::
std::ifstream f(«file.txt»); if (f) < std::stringstream buffer; buffer
Метод rdbuf() возвращает указатель на streambuf который может быть streambuf в buffer через stringstream::operator
Другая возможность (популяризированная в Effective STL от Scott Meyers ):
std::ifstream f(«file.txt»); if (f) < std::string str((std::istreambuf_iterator(f)), std::istreambuf_iterator()); // Operations on `str`. >
Это хорошо, потому что требует небольшого кода (и позволяет читать файл непосредственно в любом контейнере STL, а не только в строках), но может быть медленным для больших файлов.
ПРИМЕЧАНИЕ . Дополнительные скобки вокруг первого аргумента конструктору строк необходимы для предотвращения наиболее неприятной проблемы синтаксического анализа .
Последний, но тем не менее важный:
std::ifstream f(«file.txt»); if (f) < f.seekg(0, std::ios::end); const auto size = f.tellg(); std::string str(size, ‘ ‘); f.seekg(0); f.read( f.close(); // Operations on `str`. >
что, вероятно, является самым быстрым вариантом (из трех предложенных).
Чтение файла в контейнер
В приведенном ниже примере мы используем std::string и operator>> для чтения элементов из файла.
std::ifstream file(«file3.txt»); std::vector v; std::string s; while(file >> s) // keep reading until we run out
В приведенном выше примере мы просто итерации через файл, читающий один «элемент» за раз, используя operator>> . Этот же std::istream_iterator может быть достигнут с помощью std::istream_iterator который является итератором ввода, который считывает один «элемент» за раз из потока. Также большинство контейнеров можно построить с использованием двух итераторов, чтобы мы могли упростить приведенный выше код:
std::ifstream file(«file3.txt»); std::vector v(std::istream_iterator, std::istream_iterator<>);
Работа с текстовыми файлами в Qt
В библиотеке Qt работа с файлами вообще и текстовыми в частности реализована с помощью класса QFile.
В качестве параметра при создании объекта этого класса передаётся путь к нужному файлу.
QFile file ( «C:\test.txt» ) ;
После того как объект QFile создан, необходимо открыть файл с помощью метода open. Это метод принимает в качестве параметра режим открытия файла.
Запись в текстовый файл
После открытия текстового файла в режиме записи в него можно записать нужные данные при помощи метода write. После окончания записи файл необходимо обязательно закрыть при помощи метода close.
if ( file . open ( QIODevice :: WriteOnly ) )
file . write ( «Test stringn» ) ;
file . write ( «Test string2» ) ;
file . close ( ) ;
В данном примере, в случае успешного открытия файла в режиме записи в него будут записаны две строки. Если записываемый файл не существует, он будет создан. В противном случае он будет перезаписан.
Важно отметить, что метод write самостоятельно не добавляет разрыв строки и потому эта задача ложится на плечи программиста.
Чтение из текстового файла
Перед тем как приступить к чтению файла, его необходимо открыть в соответствующем режиме с помощью метода open. Также перед открытием файла для чтения необходимо убедиться в его существовании. Это можно сделать при помощи метода exists ( если файл существует, он возвращает true).
Для построчного чтения из текстового файла у класса QFile предусмотрен специальный метод readLine. Этот метод считывает из файла строку в начале которой в данный момент находится указатель и перемещает его в начало следующей строки.
Чтобы при чтении по ошибке позиция указателя не оказалась «за пределами» файла необходимо проверять является ли позиция указателя концом файла. Для этого служит метод atEnd, который возвратит true, когда конец файла будет достигнут. В противном случае он возвратит false.
После чтения данных из файла его также следует закрыть с помощью метода close.
Ниже приведён пример построчного чтения текстового файла.
Источник: streletzcoder.ru
1С: Работа с внешними файлами. Работа с текстовыми файлами
Примеры работы с текстовыми файлами. Запись в файл, последовательное чтение, последовательная запись, редактирование файла и др.
Другое в 1С
- 1С: Массивы и коллекции. Массивы
- Как передать структуру в параметр. Конвертация данных
- Менеджер заданий не активен. Как исправить
- Как пропорционально распределить сумму
- Как программно отключить регистрацию объектов в планах обмена при записи объекта
- Добавление текста в файл
- Запись в файл
- Последовательная запись
- Последовательное чтение
- Прочитать весь текст
- Прочитать текст построчно
- Редактирование файла
Добавление текста в файл
Пример добавления текста в файл из 1С
ПутьКФайлу = «C:tmp2.txt»; //открываем файл Текст = Новый ЗаписьТекста(); Текст.Открыть( ПутьКФайлу, КодировкаТекста.
UTF8, Символы.ПС, Истина,); //добавляем новую строчку Текст.ЗаписатьСтроку( «НоваяСтрока», Символы.
ПС); Текст.Закрыть();
Запись в файл
Пример записи текста в файл из 1С
ПутьКФайлу = «C:tmp2.txt»; //создаем файл НашФайл = Новый ТекстовыйДокумент; Выборка = Справочники.Номенклатура.
Выбрать(); //записываем построчно справочник Пока Выборка.Следующий() Цикл Строка = Выборка.Код + «|» + Выборка.
Наименование; НашФайл.ДобавитьСтроку(Строка); КонецЦикла; //сохраняем данные НашФайл.Записать(ПутьКФайлу);
Последовательная запись
Пример последовательной записи в файл из 1С
ПутьКФайлу = «C:tmp2.txt»; //создаем файл Текст = Новый ЗаписьТекста( ПутьКФайлу, КодировкаТекста.UTF8); Выборка = Справочники.Номенклатура.
Выбрать(); //записываем построчно справочник Пока Выборка.Следующий() Цикл Строка = Выборка.Код + «|» + Выборка.
Наименование; Текст.ЗаписатьСтроку(Строка); КонецЦикла; Текст.Закрыть();
Последовательное чтение
Пример последовательного чтения текстового файла из 1С
ПутьКФайлу = «C:tmp1.txt»; //создаем объект для чтения Текст = Новый ЧтениеТекста( ПутьКФайлу, КодировкаТекста.ANSI); //читаем файл построчно Пока Истина Цикл Строка = Текст.ПрочитатьСтроку(); Если Строка = Неопределено Тогда Прервать; КонецЕсли; Сообщить(Строка); КонецЦикла; Текст.Закрыть();
Прочитать весь текст
Пример чтения всего текста файла из 1С
ПутьКФайлу = «C:tmp1.txt»; //проверяем наличие файла НашФайл = Новый Файл(ПутьКФайлу); Если Не НашФайл.Существует() Тогда Сообщить(«Файл не существует»); Возврат; КонецЕсли; //читаем текст из файла ТекстовыйФайл = Новый ТекстовыйДокумент; ТекстовыйФайл.Прочитать(ПутьКФайлу); ВесьТекст = ТекстовыйФайл.ПолучитьТекст(); Сообщить(ВесьТекст);
Прочитать текст построчно
Пример построчного чтения файла из 1С
ПутьКФайлу = «C:tmp1.txt»; //читаем файла НашФайл = Новый ТекстовыйДокумент; НашФайл.Прочитать(ПутьКФайлу); //построчно заносим текст в массив Строки = Новый Массив; Для Н = 1 По НашФайл.
КоличествоСтрок() Цикл //читаем текущую строку Строка = НашФайл.ПолучитьСтроку(Н); Строки.Добавить(Строка); КонецЦикла;
Редактирование файла
Пример редактирования текстового файла из 1С
ПутьКФайлу = «C:tmp2.txt»; //читаем файл Текст = Новый ТекстовыйДокумент; Текст.Прочитать(ПутьКФайлу,); //удаляем последние две строки КолСтрок = Текст.
КоличествоСтрок(); Если КолСтрок >= 2 Тогда Текст.УдалитьСтроку(КолСтрок); Текст.
УдалитьСтроку(КолСтрок — 1); КонецЕсли; //Добавляем две строки Текст.ДобавитьСтроку(«Новая строка l»); Текст.
ДобавитьСтроку(«Новая строка 2»); //заменяем 1-ю строку Текст.ЗаменитьСтроку(1, «Новый заголовок»); //дописывает текст ко 2-й строке Текст.ЗаменитьСтроку(2, Текст.ПолучитьСтроку(2) + «|Примечание»); //сохраняем изменения Текст.Записать(ПутьКФайлу);
Источник: codely.ru