C++. Работа с текстовыми файлами

Файлы позволяют пользователю считывать большие объемы данных непосредственно с диска, не вводя их с клавиатуры. Существуют два основных типа файлов: текстовые и двоичные.

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

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

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

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

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

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

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

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

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

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

ofstream F;

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

F.open(«file», mode);

Здесь F — переменная, описанная как ofstream, file — полное имя файла на диске, mode — режим работы с открываемым файлом. Обратите внимание на то, что при указании полного имени файла нужно ставить двойной слеш. Для обращения, например к файлу accounts.txt, находящемуся в папке sites на диске D, в программе необходимо указать: D:\\sites\\accounts.txt.

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

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

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

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

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

1
2
3
4
5
6
7
8
9
10
//первый способ
ofstream F;
F.open(«D:\\sites\<strong>\</strong>accounts<strong>.</strong>txt», ios::out);
//второй способ, режим ios::out является режимом по умолчанию
//для потока ofstream
ofstream F;
F.open(«D:\\game\\noobs.txt»);
//третий способ объединяет описание переменной и типа поток
//и открытие файла в одном операторе
ofstream F («D:\\game\\noobs.txt», ios::out);

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

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

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

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

F<<a;

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

G<<b<<c<<d;

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

F.close();

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

Задача 1

Создать текстовый файл D:\\sites\\accounts.txt и записать в него n вещественных чисел.

Решение

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include «stdafx.h»
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;
int main()
{
setlocale (LC_ALL, «RUS»);
int i, n;
double a;
//описывает поток для записи данных в файл
ofstream f;
//открываем файл в режиме записи,
//режим ios::out устанавливается по умолчанию
f.open(«D:\\sites\\accounts.txt», ios::out);
//вводим количество вещественных чисел
cout<<«n=»; cin>>n;
//цикл для ввода вещественных чисел
//и записи их в файл
for (i=0; i<n; i++)
{
cout<<«a=»;
//ввод числа
cin>>a;
f<<a<<«\t«;
}
//закрытие потока
f.close();
system(«pause»);
return 0;
}

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

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

1
2
ifstream F;
F.open(«D:\\sites\\accounts.txt», ios::in);

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

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

F>>a;

Два числа в текстовом редакторе считаются разделенными, если между ними есть хотя бы один из символов: пробел, табуляция, символ конца строки. Хорошо, когда программисту заранее известно, сколько и какие значения хранятся в текстовом файле. Однако часто известен лишь тип значений, хранящихся в файле, при этом их количество может быть различным. Для решения данной проблемы необходимо считывать значения из файла поочередно, а перед каждым считыванием проверять, достигнут ли конец файла. А поможет сделать это функция F.eof(). Здесь F — имя потока функция возвращает логическое значение: true или false, в зависимости от того достигнут ли конец файла.

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

1
2
3
4
5
6
7
8
9
//организуем для чтения значений из файла, выполнение
//цикла прервется, когда достигнем конец файла,
//в этом случае F.eof() вернет истину
while (!F.eof())
{
//чтение очередного значения из потока F в переменную a
F>>a;
//далее идет обработка значения переменной a
}

Для лучшего усвоения материала рассмотрим задачу.

Задача 2

В текстовом файле D:\\game\\accounts.txt хранятся вещественные числа, вывести их на экран и вычислить их количество.

Решение

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include «stdafx.h»
#include <iostream>
#include <fstream>
#include <iomanip>
#include <stdlib.h>
using namespace std;
int main()
{
setlocale (LC_ALL, «RUS»);
int n=0;
float a;
fstream F;
//открываем файл в режиме чтения
F.open(«D:\\sites\\accounts.txt»);
//если открытие файла прошло корректно, то
if (F)
{
//цикл для чтения значений из файла; выполнение цикла прервется,
//когда достигнем конца файла, в этом случае F.eof() вернет истину.
while (!F.eof())
{
//чтение очередного значения из потока F в переменную a
F>>a;
//вывод значения переменной a на экран
cout<<a<<«\t«;
//увеличение количества считанных чисел
n++;
}
//закрытие потока
F.close();
//вовод на экран количества считанных чисел
cout<<«n=»<<n<<endl;
}
//если открытие файла прошло некорректно, то вывод
//сообщения об отсутствии такого файла
else cout<<» Файл не существует»<<endl;
system(«pause»);
return 0;
}

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


Похожие записи:

28 комментарий
    • Как мне сделать так, чтобы 1я часть информации записывалась в 1ю строку, а 2я часть информации записывалась во 2ю строку?

      Вот немного переработал один из примеров этой статьи… Он рассчитан именно на две строки в файле.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      #include "stdafx.h"
      #include <iostream>
      #include <fstream>
      #include <string>
      using namespace std;
      int main()
      {
       setlocale (LC_ALL, "RUS");
      int i, x=0;
      string a;
       ofstream f;
      f.open("noobs.txt", ios::out);
      cout<<"Для перехода на новую строку введите *"<<endl;
      while (x<2)
      {
      a=’\0′;
      while (a!="*")
      {
      getline(cin, a);
      if (a!="*") f<<a<<"\t";
      }
      f<<endl;
      x++;
      }
      f.close();
      system("pause");
      return 0;
      }
      Ответить
  • Спасибо большое) очень полезный пост) только подскажите вот например если мне надо считывать количество строк из файла, как мне это анписать? опишите поподробней, вы выше указали что cout<<n; при чтении с файла заменяется F<<n; но как же используется например getc или getline при чтении из файла?

    Ответить
    • но как же используется, например getc или getline при чтении из файла?

      getline можно использовать, как для построчного ввода информации в файл (например, cin.getline(c, 256)), так и для вывода ее от туда (например, f.getline(c, 256);).

      подскажите вот, например, если мне надо считывать количество строк из файла, как мне это написать?

      Это можно сделать при помощи того же getline. Вот код программы:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
       #include "stdafx.h"
       #include <iostream>
       #include <fstream>
       using namespace std;
       int main()
       {
       setlocale (LC_ALL, "RUS");
       int i, k=0;
       char c[256];
       fstream f;
       f.open("noobs.txt", ios::in);
       while (!f.eof())
       {
       f.getline(c, 256);
       k++;
       }
       cout<<"В файле "<<k<<" строк(а/и)";
       f.close();
       system("pause>>void");
       return 0;
       }
      Ответить
  • Спасибо большое за примеры ! Но у меня вот есть вопрос, при выводе данных из файла последний символ повторяется . Ну вот в файле : q 2 e 2 он выводит :q 2 e 2 2 ?

    Ответить
    • Возможно, Вы используете в качестве временной, переменную типа char? Поскольку если взять программу из последнего примера и верно заполненный файл (пробелы между числами), то все должно работать нормально.
      Если нужно вывести значения при помощи символьной переменной, то можно воспользоваться несколькими способами, например, не изменяя операторов, поступить так:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      int n=0;
      char a;
      fstream F;
      F.open("noobs.txt");
      if (F)
      {
      F>>a;
      while (F.eof()==’\0′)
      {
      cout<<a;
      F>>a;
      n++;
      }
       F.close();
      cout<<"\n n="<<n<<endl;
      }
      else cout<<" Файл не существует"<<endl;
      Ответить
  • Доброго время суток. Подскажите, пожалуйста, мне надо записать структуры в текстовый файл. Ввод данных с клавиатуры. Не могли бы вы показать пример подобной программы.

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

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      #include "stdafx.h"
      #include <iostream>
      #include <fstream>
      using namespace std;
      struct example //определение структуры
      {
      int a[3];
      char c;
      };
      example x; //определение переменных типа struct example
      void main()
      {
      ofstream f;
      f.open("accounts.txt", ios::out);
      cout<<"Symbol > "; cin>>x.c;
      f<<x.c<<"\t"; //запись переменной типа struct example в файл
      for (int i=0; i<3; i++)
      {
      cout<<"mas["<<i<<"] > "; cin>>x.a[i];
      f<<x.a[i]<<"\t"; //запись переменной типа struct example в файл
      }
      f.close();
      system("pause>>void");
      }
      Ответить
  • доброго времени суток! Затрудняюсь с кодом программы которая из 2-х txt файлов записывает в третий «куски» содержимого текста. Спасибо за помощь!

    Ответить
  • Спасибо за пояснения) Но вот случай,если надо считать данные из файла,выполнить с ними некие манипуляции и записать результат в другой файл. Как быть в такой ситуации?

    Ответить
    • 1. открыть файл_1 в режиме чтения;
      2. считать из него данные в переменную;
      3. закрыть файл_1;
      4. произвести над данными необходимые операции;
      5. открыть файл_2 в режиме записи;
      6. записать в него обработанные данные;
      7. закрыть файл_2;
      Если возникают сложности, то посмотрите сначала решение задачи 2, а потом задачи 1.

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

    Ответить
    • 1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      int a, b, c;
      fstream F;
      F.open("out.txt");
      while (!F.eof()) F>>a>>b>>c;
      F.close();
      c=a%b;
      a=b;
      b=c;
      F.open("in.txt", ios::out);
      F<<a<<"\t"<<b<<"\t"<<c;
      F.close();

      Что-то типа этого думаю подойдет. Нужно верно указать путь к файлу, т. е. в примере он лежит в той же папке, что и проект (в Windows это примерно следующей адрес: C:\Users\Пользователь\Documents\Visual Studio версия\Projects\имя_проекта\имя_проекта).

      Ответить
  • Дан файл, содержащий зашифрованный русский текст. Каждая буква заменяется на следующую за ней (Буква Я заменяется на букву А). Получить в новом файле расшифровки данного текста.

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

    Ответить
    • 1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      #include "stdafx.h"
      #include <iostream>
      #include <fstream>
      #include <string>
      #include <windows.h>
      using namespace std;
      void main()
      {
      SetConsoleCP(1251); SetConsoleOutputCP(1251);
      string s; int i=0;
      fstream F;
      F.open("out.txt");
      getline(F, s);
      while (i<s.length())
      {
          if (int(s[i])+255!=32)
          {
              if ((int(s[i])+255)>190 && (int(s[i])+255)<256)
              {
              if (int(s[i])+255==191) s[i]=int(s[i])+31;
              else if (int(s[i])+255==223) s[i]=int(s[i])+31;
              else s[i]=int(s[i])-1;
              }
          }
          i++;
      }
      F.close();
      F.open("in.txt", ios::out);
      F<<s;
      F.close();
      system("pause>>void");
      }
      Ответить
    • Не понял, что Вы имеете в виду под фразой «заменить на две аналогичных», но, думаю, следующий листинг Вам поможет. Просто скорректируйте его под себя.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      #include "stdafx.h"
      #include <iostream>
      #include <fstream>
      #include <string>
      using namespace std;
      void main()
      {
      string s; int i=0;
      fstream F;
      F.open("1.txt");
      getline(F, s);
      while (i<s.length())
      {
          int count=int(s[i]);
          switch (count)
          {
          case 97: s[i]=‘|’; break;
          case 101: s[i]=‘|’; break;
          case 105: s[i]=‘|’; break;
          case 111: s[i]=‘|’; break;
          case 117: s[i]=‘|’; break;
          }
          i++;
      }
      F.close();
      F.open("1.txt", ios::out);
      F<<s;
      F.close();
      system("pause>>void");
      }
      Ответить
  • Здравствуйте! Спасибо Вам за столь подробное разжевывание-Вы очень хорошо объясняете. Я вот пытаюсь одну задачку решить, вроде как не сложная, но у меня не получается. Вот условие: «Дописать к файлу 1.txt количество слов в последних n строках файла 2.txt « Я вот Выше увидел Ваше решение насчет вывода количества строк в файле (обозначено как k). Может нужно таким образом выяснить количество строк в файле 2.txt, а потом вычесть n из k, а получившуюся разность считать количеством строк, после которых нужно начинать считать количество слов до конца файла. Тогда получается, что кроме количества строк, в массив надо записать и значения этих строк, чтобы потом посчитать количество слов в них. Ну и чтобы результат записать в конец файла 1.txt, надо определить последний символ в этом файле (вероятно надо циклом перебрать весь файл, пока не достигнем eof) и после него дописать полученное количество. У меня че-то пока не получается-и вообще может я и рассуждаю неправильно?. Помогите пожалуйста!

    Ответить
  • Здравствуйте! Помогите пожалуйста, нужен пример программы которая способна разбить какой-либо файл на части по указанному количеству строк и записать эти части каждую в отдельный файл. Имя входного файла вводит пользователь.
    Еще программа чтоб могла составлять один главный файл из различных частей, находящихся в различных файлах.
    За ранее благодарен!!! ))

    Ответить
  • Здравствуйте. Спасибо за материал, но можете помочь если не трудно? Мне нужно открыть файл .txt, в нем таблица, и надо что бы с ее столбцами и строками можно било делать различние операции как полностю показать все дание в столбце или строке, так же среднее всех ячеек и найти максимум, минимум столбуов или строк. Спасибо.

    Ответить
  • Здравствуйте. Помогите пожалуйста с задачей.
    Даны три матрицы: A, B, C. Каждая размерностью 3×3. Каждая находится в отдельном файле. Их необходимо вызвать выполнить действия: ((A-B)+C)*A.
    Результат необходимо сохранить в матрицу D и сохранить эту матрицу в файл.

    Ответить
  • Добрый вечер, можете помочь с программой:
    Напишите программу myrm, имеющую один аргумент и удаляющую файл, имя которого задано.
    Пример вызова: ./myrm test.txt

    Ответить

Оставить комментарий

Ваш e-mail не будет опубликован. Обязательные поля отмечены *