«

»

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 — переменная, описанная как ofstreamfile — полное имя файла на диске, 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 необходимо указать имя открытого файла.

Например, для записи в поток переменной 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(). Здесь — имя потока функция возвращает логическое значение: 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. harddan9

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

    1. А. С. Третьяков

      Как мне сделать так, чтобы 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;
      }
  2. Лена

    Спасибо огромное, вы мне очень помогли! Было бы здорово, если бы так же хорошо было рассказано еще и про С :)

  3. botdjra

    Спасибо большое) очень полезный пост) только подскажите вот например если мне надо считывать количество строк из файла, как мне это анписать? опишите поподробней, вы выше указали что cout<<n; при чтении с файла заменяется F<<n; но как же используется например getc или getline при чтении из файла?

    1. А. С. Третьяков

      но как же используется, например 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;
       }
  4. AB

    Спасибо большое за примеры ! Но у меня вот есть вопрос, при выводе данных из файла последний символ повторяется . Ну вот в файле : q 2 e 2 он выводит :q 2 e 2 2 ?

    1. А. С. Третьяков

      Возможно, Вы используете в качестве временной, переменную типа 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
      int n=0; char a;
       FILE *F;
       F=fopen("noobs.txt", "r");
      if (F)
      {a=getc(F);
      while (!feof(F))
      {
      cout<<a;
      a=getc(F);
      n++;
      }
      cout<<"\n n="<<n<<endl;
      }
      else cout<<" Файл не существует"<<endl;
  5. AB

    спасибо) все поняла !

  6. kotyra211

    Большое спасибо!очень помогло

  7. Ro De Fox

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

    1. А. С. Третьяков

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

      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");
      }
  8. Danik

    доброго времени суток! Затрудняюсь с кодом программы которая из 2-х txt файлов записывает в третий «куски» содержимого текста. Спасибо за помощь!

  9. Tim

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

    1. А. С. Третьяков

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

      1. Tim

        #include «stdafx.h»
        #include
        #include
        #include
        using namespace std;
        int main(void)
        {
        setlocale(LC_ALL, «RUS»);
        int a,b,c;
        fstream F;
        F.open(«test.txt»);
        if (F)
        {
        //цикл для чтения значений из файла; выполнение цикла прервется,
        //когда достигнем конца файла, в этом случае F.eof() вернет истину.
        while (!F.eof())
        {
        //чтение очередного значения из потока F в переменную a
        F>>a;
        cout<<a<>b;
        cout<<b<<"\t";
        }
        F.close();
        else cout<<" Файл не существует"<<endl;
        while (b) {
        c = a % b;
        a = b;
        b = c;
        }
        F.open("test1.txt",ios::out);

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

        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. Tim

            Спасибо большое. Помогло.

  10. Вектор

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

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

    1. А. С. Третьяков
      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");
      }
  11. Petya

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

    1. А. С. Третьяков

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

      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");
      }
  12. Honest

    Здравствуйте! Спасибо Вам за столь подробное разжевывание-Вы очень хорошо объясняете. Я вот пытаюсь одну задачку решить, вроде как не сложная, но у меня не получается. Вот условие: «Дописать к файлу 1.txt количество слов в последних n строках файла 2.txt « Я вот Выше увидел Ваше решение насчет вывода количества строк в файле (обозначено как k). Может нужно таким образом выяснить количество строк в файле 2.txt, а потом вычесть n из k, а получившуюся разность считать количеством строк, после которых нужно начинать считать количество слов до конца файла. Тогда получается, что кроме количества строк, в массив надо записать и значения этих строк, чтобы потом посчитать количество слов в них. Ну и чтобы результат записать в конец файла 1.txt, надо определить последний символ в этом файле (вероятно надо циклом перебрать весь файл, пока не достигнем eof) и после него дописать полученное количество. У меня че-то пока не получается-и вообще может я и рассуждаю неправильно?. Помогите пожалуйста!

  13. Honest

    А все, уже не надо, сам написал)) Не очень компактно получилось, зато все работает))

  14. Nazar

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

  15. Carbon

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

  16. Phoenix

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

  17. Daniiil

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

  18. андрей

    Нужна помочт с программой компютерная диагностки аудио видео радио аппаратуры я новичек не знаю с чего начать?

Добавить комментарий

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

Вы можете использовать эти теги HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Проверка на человечность *