С как записать в текстовый файл массив

Обновлено: 06.07.2024

Текстовыми называют файлы, состоящие из любых символов. Они организуются по строкам, каждая из которых заканчивается символом "конец строки". Конец самого файла обозначается символом " конец файла ". При записи информации в текстовый файл , просмотреть который можно с помощью любого текстового редактора, все данные преобразуются к символьному типу и хранятся в символьном виде.

Для работы с файлами используются специальные типы данных, называемые потоками 4 Вообще говоря, потоки являются классами, которым будет посвящена специальная глава. . Поток ifstream служит для работы с файлами в режиме чтения. Поток ofstream служит для работы с файлами в режиме записи. Для работы с файлами в режиме как чтения, так и записи служит поток iofstream .

В программах на C++ при работе с текстовыми файлами необходимо подключать библиотеки iostream и fstream .

Для того, чтобы записать данные в текстовый файл , необходимо:

  1. Описать переменную типа ofstream.
  2. Открыть файл с помощью функции open.
  3. Вывести информацию в файл.
  4. Закрыть файл.

Для того, чтобы считать данные из текстового файла, необходимо:

  1. Описать переменную типа ifstream.
  2. Открыть файл с помощью функции open.
  3. Считать информацию из файла, при считывании каждой порции данных необходимо проверять достигнут ли конец файла.
  4. Закрыть файл.

7.2.1 Запись информации в текстовый файл

Для того, чтобы начать работать с текстовым файлом, необходимо описать переменную типа ofstream . Например, с помощью оператора

ofstream F; 5 Далее термин "поток" будет использоваться для указания переменной, описанной как ofstream, ifstream, iofstream , а термин "файл" для указания реального файла на диске.

будет создана переменная F для записи информации в файл. На следующем этапе файл необходимо открыть для записи. В общем случае оператор открытия потока будет иметь вид:

Здесь F — переменная, описанная как ofstream, file — имя файла на диске, mode — режим работы с открываемым файлом.

Файл может быть открыт в одном из следующих режимов:

  • ios::in — открыть файл в режиме чтения данных, этот режим является режимом по умолчанию для потоков ifstream;
  • ios::out — открыть файл в режиме записи данных (при этом информация в существующем файле уничтожается), этот режим является режимом по умолчанию для потоков ofstream ;
  • ios::app — открыть файл в режиме записи данных в конец файла;
  • ios::ate — передвинуться в конец уже открытого файла;
  • ios::trunc — очистить файл, это же происходит в режиме ios::out;
  • ios::nocreate — не выполнять операцию открытия файла, если он не существует 6 При открытии файла в режиме ios::in происходит как раз обратное, если файл не существует, он создаётся ;
  • ios::noreplace — не открывать существующий файл.

Параметр mode может отсутствовать, в этом случае файл открывается в режиме по умолчанию для данного потока 7 ios::in — для потоков ifstream, ios::out — для потоков ofstream . .

После удачного открытия файла (в любом режиме) в переменной F будет храниться true , в противном случае false . Это позволит проверять корректность операции открытия файла.

Открыть файл (в качестве примера возьмём файл abc.txt ) в режиме записи можно одним из следующих способов:

После открытия файла в режиме записи будет создан пустой файл, в который можно будет записывать информацию. Если нужно открыть файл, чтобы в него что-либо дописать, то в качестве режима следует использовать значение ios::app .

После открытия файла в режиме записи, в него можно писать точно также, как и на экран, только вместо стандартного устройства вывода cout необходимо указать имя открытого для записи файла.

Например, для записи в поток F переменной a оператор вывода будет иметь вид:

Для последовательного вывода в поток G переменных b, c и d оператор вывода станет таким:

Закрытие потока осуществляется с помощью оператора:

В качестве примера рассмотрим следующую задачу.

Задача 7.1. Создать текстовый файл abc.txt и записать туда n вещественных чисел.

Текст программы с комментариями:

Обратите внимание, что в текстовый файл записываются не только вещественные числа, но и символы табуляции. Таким образом, в конце файла после последнего числа находится символ табуляции. По этой причине может возникнуть проблема при чтении информации (п. 7.2.2), так как символ табуляции будет интерпретирован как вещественное число. Чтобы этого избежать в программе была применена следующая конструкция:

Здесь реализована проверка ввода последнего числа. После него символ табуляции отсутствует.

В результате работы программы будет создан текстовый файл abc.txt , который можно просмотреть средствами обычного текстового редактора (рис. 7.1,рис. 7.2).

7.2.2 Чтение информации из текстового файла

Процесс работы программы к задаче 7.1. Ввод исходных данных.


Рис. 7.1. Процесс работы программы к задаче 7.1. Ввод исходных данных.

Текстовый файл abc.txt, созданный программой к задаче 7.1.


увеличить изображение
Рис. 7.2. Текстовый файл abc.txt, созданный программой к задаче 7.1.

Для того, чтобы прочитать информацию из текстового файла, необходимо описать переменную типа ifstream . После этого файл необходимо открыть для чтения с помощью оператора open . Если переменную назвать F , то первые два оператора будут такими:

8 Указание режима ios::in можно, конечно, опустить, ведь для потока ifstream значение ios::in является значением по умолчанию, тогда оператор open можно будет записать так F.open("abc.txt");

После открытия файла в режиме чтения, из него можно считывать информацию точно так же, как и с клавиатуры, только вместо стандартного устройства ввода cin необходимо указать имя потока, из которого будет происходить чтение данных.

Например, для чтения из потока F в переменную a оператор ввода будет иметь вид:

Для последовательного ввода из потока G в переменные b, с и d оператор ввода станет таким:

Два числа в текстовом файле считаются разделёнными, если между ними есть хотя бы один из символов: пробел, табуляция, символ конца строки.

Хорошо, если программисту заранее известно, сколько и каких значений хранится в текстовом файле. Однако часто просто известен тип значений, хранящихся в файле, при этом количество значений в файле может быть различным. При решении подобной проблемы необходимо считывать значения из файла по одному, а перед каждым считыванием проверять, достигнут ли конец файла. Для проверки, достигнут или нет конец файла, служит функция

Здесь F — имя потока, функция возвращает логическое значение: true — если достигнут конец файла, если не достигнут функция возвращает значение false .

Следовательно, цикл для чтения содержимого всего файла можно записать так.

Рассмотрим следующую задачу.

abc.txt

Задача 7.2. В текстовом файле хранятся вещественные числа (рис. 7.2), вывести их на экран и вычислить их количество.

Текст программы с комментариями приведён ниже.

Результат работы программы к задаче 7.2:

Программа работает корректно, если текстовый файл abc.txt был создан с помощью программы к задаче 7.1. Предположим, что файл создавался в текстовом редакторе, и пользователь ввёл после последней цифры символ пробела, табуляции или перехода на новую строку. Тогда результат будет таким:

Происходит это потому, что после чтения последней цифры из потока конец файла не достигнут, оператор цикла выполняется ещё один раз, значение переменной увеличивается на единицу, а так как значение переменной не изменилось, то выводится повторно. Один из способов решения данной проблемы может быть таким:

Если количество вещественных чисел, записанных в файл, известно заранее, то текст программы можно переписать следующим образом:

Существует возможность открывать файл с данными таким образом, чтобы в него можно было дописывать информацию. Рассмотрим эту возможность на примере решения следующей задачи.

abc.txt

Задача 7.3. В файле (рис. 7.2) хранится массив вещественных чисел, дописать в файл этот же массив, упорядочив его по возрастанию.

Алгоритм решения задачи очень простой. Считываем в массив данные из текстового файла, упорядочиваем массив, дописываем его в этот же файл.

Для чтения данных из файла описываем поток ifstream , открываем его в режиме чтения и последовательно, пока не достигнем конца файла, считываем все элементы в массив. Сортировку проведём методом пузырька. Обратите внимание, что поток нужно открыть так, чтобы была возможность дописать в конец файла упорядоченный массив.

До этого при вводе-выводе данных мы работали со стандартными потоками — клавиатурой и монитором. Теперь рассмотрим, как в языке C реализовано получение данных из файлов и запись их туда. Перед тем как выполнять эти операции, надо открыть файл и получить доступ к нему.

В языке программирования C указатель на файл имеет тип FILE и его объявление выглядит так:

С другой стороны, функция fopen() открывает файл по указанному в качестве первого аргумента адресу в режиме чтения ("r"), записи ("w") или добавления ("a") и возвращает в программу указатель на него. Поэтому процесс открытия файла и подключения его к программе выглядит примерно так:

Примечание. В случае использования относительной адресации текущим/рабочим каталогом в момент исполнения программы должен быть тот, относительно которого указанный относительный адрес корректен. Место нахождения самого исполняемого файла не важно.

При чтении или записи данных в файл обращение к нему осуществляется посредством файлового указателя (в данном случае, myfile).

Если в силу тех или иных причин (нет файла по указанному адресу, запрещен доступ к нему) функция fopen() не может открыть файл, то она возвращает NULL. В реальных программах почти всегда обрабатывают ошибку открытия файла в ветке if , мы же далее опустим это.

Объявление функции fopen() содержится в заголовочном файле stdio.h, поэтому требуется его подключение. Также в stdio.h объявлен тип-структура FILE.

После того, как работа с файлом закончена, принято его закрывать, чтобы освободить буфер от данных и по другим причинам. Это особенно важно, если после работы с файлом программа продолжает выполняться. Разрыв связи между внешним файлом и указателем на него из программы выполняется с помощью функции fclose() . В качестве параметра ей передается указатель на файл:

В программе может быть открыт не один файл. В таком случае каждый файл должен быть связан со своим файловым указателем. Однако если программа сначала работает с одним файлом, потом закрывает его, то указатель можно использовать для открытия второго файла.

Чтение из текстового файла и запись в него

fscanf()

Функция fscanf() аналогична по смыслу функции scanf() , но в отличии от нее осуществляет форматированный ввод из файла, а не стандартного потока ввода. Функция fscanf() принимает параметры: файловый указатель, строку формата, адреса областей памяти для записи данных:

Возвращает количество удачно считанных данных или EOF. Пробелы, символы перехода на новую строку учитываются как разделители данных.

Допустим, у нас есть файл содержащий такое описание объектов:

Тогда, чтобы считать эти данные, мы можем написать такую программу:

В данном случае объявляется структура и массив структур. Каждая строка из файла соответствует одному элементу массива; элемент массива представляет собой структуру, содержащую строковое и два числовых поля. За одну итерацию цикл считывает одну строку. Когда встречается конец файла fscanf() возвращает значение EOF и цикл завершается.

fgets()

Функция fgets() аналогична функции gets() и осуществляет построчный ввод из файла. Один вызов fgets() позволят прочитать одну строку. При этом можно прочитать не всю строку, а лишь ее часть от начала. Параметры fgets() выглядят таким образом:

Такой вызов функции прочитает из файла, связанного с указателем myfile, одну строку текста полностью, если ее длина меньше 50 символов с учетом символа '\n', который функция также сохранит в массиве. Последним (50-ым) элементом массива str будет символ '\0', добавленный fgets() . Если строка окажется длиннее, то функция прочитает 49 символов и в конце запишет '\0'. В таком случае '\n' в считанной строке содержаться не будет.

В этой программе в отличие от предыдущей данные считываются строка за строкой в массив arr. Когда считывается следующая строка, предыдущая теряется. Функция fgets() возвращает NULL в случае, если не может прочитать следующую строку.

getc() или fgetc()

Функция getc() или fgetc() (работает и то и другое) позволяет получить из файла очередной один символ.

Приведенный в качестве примера код выводит данные из файла на экран.

Запись в текстовый файл

Также как и ввод, вывод в файл может быть различным.

  • Форматированный вывод. Функция fprintf ( файловый_указатель, строка_формата, переменные ) .
  • Посточный вывод. Функция fputs ( строка, файловый_указатель ) .
  • Посимвольный вывод. Функция fputc() или putc( символ, файловый_указатель ) .

Ниже приводятся примеры кода, в которых используются три способа вывода данных в файл.

Запись в каждую строку файла полей одной структуры:

Построчный вывод в файл ( fputs() , в отличие от puts() сама не помещает в конце строки '\n'):

Пример посимвольного вывода:

Чтение из двоичного файла и запись в него

С файлом можно работать не как с последовательностью символов, а как с последовательностью байтов. В принципе, с нетекстовыми файлами работать по-другому не возможно. Однако так можно читать и писать и в текстовые файлы. Преимущество такого способа доступа к файлу заключается в скорости чтения-записи: за одно обращение можно считать/записать существенный блок информации.

При открытии файла для двоичного доступа, вторым параметром функции fopen() является строка "rb" или "wb".

Тема о работе с двоичными файлами достаточно сложная, для ее изучения требуется отдельный урок. Здесь будут отмечены только особенности функций чтения-записи в файл, который рассматривается как поток байтов.

Функции fread() и fwrite() принимают в качестве параметров:

  1. адрес области памяти, куда данные записываются или откуда считываются,
  2. размер одного данного какого-либо типа,
  3. количество считываемых данных указанного размера,
  4. файловый указатель.

Эти функции возвращают количество успешно прочитанных или записанных данных. Т.е. можно "заказать" считывание 50 элементов данных, а получить только 10. Ошибки при этом не возникнет.

Пример использования функций fread() и fwrite() :

Здесь осуществляется попытка чтения из первого файла 50-ти символов. В n сохраняется количество реально считанных символов. Значение n может быть равно 50 или меньше. Данные помещаются в строку. То же самое происходит со вторым файлом. Далее первая строка присоединяется ко второй, и данные сбрасываются в третий файл.

В этой статье есть несколько примеров, демонстрирующих различные способы записи текста в файл. В первых двух примерах используются удобные статические методы класса System.IO.File для записи каждого элемента любого объекта IEnumerable<string> и string в текстовый файл. В третьем примере показано, как добавить текст в файл, если необходимо обрабатывать отдельно каждую строку по мере ее записи в файл. В первых трех примерах происходит перезапись всего существующего содержимого файла. В последнем примере показано, как добавить текст в существующий файл.

Запись коллекции строк в файл

Предыдущий пример исходного кода:

Создает экземпляр массива строк с тремя значениями.

  • Асинхронно создает имя файла WriteLines.txt. Если целевой файл уже существует, он будет перезаписан.
  • Записывает заданные строки в файл.
  • Закрывает файл, выполняет автоматическую очистку и удаление по мере необходимости.

Запись одной строки в файл

Предыдущий пример исходного кода:

Создает экземпляр строки с заданным назначенным строковым литералом.

  • Асинхронно создает имя файла WriteText.txt. Если целевой файл уже существует, он будет перезаписан.
  • Записывает заданный текст в файл.
  • Закрывает файл, выполняет автоматическую очистку и удаление по мере необходимости.

Запись выбранных строк из массива в файл

Предыдущий пример исходного кода:

  • Создает экземпляр массива строк с тремя значениями.
  • Создает экземпляр StreamWriter с путем к файлу WriteLines2.txt как с помощью объявления.
  • Выполняет итерацию по всем строкам.
  • Условно ожидает вызов StreamWriter.WriteLineAsync(String), который записывает строку в файл, если строка не содержит "Second" .

Добавление текста в существующий файл

Предыдущий пример исходного кода:

  • Создает экземпляр массива строк с тремя значениями.
  • Создает экземпляр StreamWriter с путем к файлу WriteLines2.txt как с помощью объявления, передавая true для добавления.
  • Ожидает вызов StreamWriter.WriteLineAsync(String), который записывает строку в файл как добавленную строку.

Исключения

При следующих условиях возможно возникновение исключения:

    : Файл существует и является файлом только для чтения. : Имя пути имеет слишком большую длину. : Диск может быть переполнен.

Существуют дополнительные условия, которые могут привести к возникновению исключений при работе с файловой системой, поэтому программировать следует с осторожностью.

Чтение из файла

Добрый день! В этой статье я расскажу о том, как написать программу, которая будет считывать строки из файла. Покажу как записать их в массив или вывести. При написании программы будут использоваться функции из стандартной библиотеки языка C++.

Стандартная библиотека языка C++ <fstream> включает множество функций для работы с файлами. Описание функций можно найти в сети или в учебниках по C++. Здесь же я опишу одну, которая позволит произвести чтение строки из файла.

Содержание файла strings.txt

Три строки, содержащиеся в файле, я запишу массив и выведу на экран.

Пингвин читает содержимое файла

Переходим к написанию программы на C++.

Нашей программе понадобятся два заголовочных файла <iostream> и <fstream>. Первый нужен будет для использования вывода на консоль, второй для работы с файлами.

Объявим две целочисленные константы len и strings, они будут хранить максимальную длину наших строк и количество строк. Объявим символьную константу ch, которая будет хранить разделяющий символ. Первые две константы будут использоваться для объявления массива. Мой файл содержит 3 строки

При помощи значений двух первых констант объявим двумерный массив символов.

Создадим объект класса ostream, в конструктор поместим адрес файла, флаги открытия.

Флаг ios::in позволяет открыть файл для считывания, ios::binary открывает его в двоичном режиме.

Далее стоит проверить открылся ли файл, если не открылся, то завершаем работу программы.

В данный момент программа имеет такой вид

Теперь остается описать алгоритм считывания строк из файла и занесения их в массив с последующим выводом. Для этого понадобится цикл от нуля до strings с инкрементом переменной r. Во время каждого прохода цикла используем перегруженную функцию getline() объекта fs с тремя аргументами.

fs.getline(Массив_символов, Макс_длина_строки, Разделитель_строк)

Функция считывает символы из файла, пока не считает количество равное Макс_длина_строки, либо не встретит на своём пути символ равный Разделитель_строк, а после записывает считанные символы в Массив_символов. В качестве разделителя в моём текстовом файле используется перенос строки.

После сразу же выводим содержимое строки, хранящееся в массиве, при помощи поточного вывода в консоль cout.

Весь листинг конечной программы

За счет константных переменных её можно легко модернизировать. Изменив константу strings, можно указать количество выводимых строк. Чтение из файла будет производится до тех пор, пока массив не заполнится нужным количеством строк. Изменив константу ch, можно изменить разделитель строк(Например, можно разделять их пробелом и занести в массив отдельные слова из файла и т.д.).

Если Вас интересует запись в файл, то почитайте статью о чтении из input.txt и записи данных в файл output.txt.

Пример работы string и пример считывания всех строк из файла в массив с последующим выводом

Читайте также: