Работа с файлами в C++

№76-1,

педагогические науки

В работе рассмотрены способы работы с файлами на языке программирования С++. Приведенные программы могут быть использованы при решении задач контрольных и лабораторных работ.

Похожие материалы

Язык программирования С++ обеспечивает несколько способов работы с файлами. Рассмотрим способ потока. Поток является некоторым абстрактным понятием, который относится к любому переносу данных (последовательность байтов) от источника к приемнику. Операция записи информации в поток называется включением информации, а чтение информации из потока извлечением. Эти операции выполняются через буфер. Потоки бывают входные (информация заносится в память), выходные (информация считывается из памяти), а также двунаправленные (допускается как чтение информации, так и запись) [1-5].

Для работы с файловыми потоками применяются классы istream и ostream. Эти классы базовые для класса iostream, который реализует двунаправленный поток. Чтобы применить в программе этих классов нужно подключить соответствующие заголовочные файлы.

Преимущества работы с файлами используя поток по сравнению с функциями ввода-вывода — контроль типов и работа с типами пользователя. Недостаток работы с использованием потока — это уменьшение быстродействия программы.

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

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

  1. открытие файла (для записи информации, добавления или чтения);
  2. запись информации в файл или считывание её с файла;
  3. закрытие файла.

При закрытии файл отсоединяется от потока.

Чтобы связать поток с файлом, нужно использовать управляющую структуру (указатель файла), которая имеет тип FILE. Эта структура содержит всю информацию о файле.

Используя FILE, переменная типа указатель файла объявляется следующим образом:

FILE * myfile;

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

FILE *fopen (const char *file_name, const char *file_mode);

Здесь *file_name — это имя файла, перед именем можно указать путь к файлу. Параметр *file_mode определяет режим открытия файла.

Если при выполнении операции открытия файла вышла ошибка, то fopen() вернет NULL, т.е. пустой указатель.

Файл закрывается с помощью функции fclose():

int fclose(FILE *myfile);

Здесь myfile указатель файла.

Cимвола с файла можно считать используя функцию fgetc():

int fgetc(FILE *myfile);

fgetc() возвращает целочисленное значение. Символ находится в младшем разряде. В том случае, если чтение произошло без ошибок, то старший разряд равен нулю. При чтении признака конца файла функция fgetc() вернет значение EOF.

Символ в файл записывается с помощью функции fputc():

int fputc( int сh, FILE *myfile);

Здесь сh — записываемый символ. В файл записывается только младший разряд сh.

Для определения достигнут ли конец файла, необходимо использовать функцию feof():

int feof(FILE *myfile);

При чтении признака конца файла feof() вернет true, а иначе — false.

Задача

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

Решение
/* В начале подключаем четыре заголовочных файла: iostream.h (содержит cin и cout), stdio.h (содержит тип FILE и все функции для работы с файлами), stdlib.h (содержит exit()), conio.h (содержит getch()).*/
void main(){
FILE *inmyfile, *outmyfile;
char mych, FileRead[]="d:\\old.txt", FileWrite[]="d:\\new.txt";
inmyfile = fopen(FileRead,"rb");
outmyfile = fopen(FileWrite,"wb");
if (inmyfile==NULL)
{ cout<<" ошибка возникла при открытии файла"; getch(); exit(1); }
/* Если не удалось открыть файл, то выводим об этом сообщение на экран и выходим из функции main(), т.е. из программы в данном случае */
if (outmyfile==NULL)
{ cout<<" ошибка при создании файла"; getch();exit(1); }
/* Если не удалось создать файл, то также завершаем работу программы  */
/*в следующем цикле происходит копирование файла*/
while(!feof(inmyfile)) { mych = fgetc(inmyfile);
if(!strrchr("0123456789",mych))
fputc(mych,outmyfile);
}
fclose(inmyfile);
fclose(outmyfile);
}

Данные из файла можно считывать и записывать строками. Для этого используются функции fgets() и fputs():

int fputs(const char *mys, FILE *myfilename);
char *fgets(char *mys, int n, FILE *myfilename);

Здесь параметр n — это длина строки, *mys — указатель на строку.

Задача

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

Решение
/* В начале подключаем четыре заголовочных файла: iostream.h, stdio.h, stdlib.h, conio.h.*/
void  main(){
char mystr[256];
FILE * myfile= fopen("d:\\Testmy.txt","w");
if ( myfile==NULL)
{ cout<<” ошибка возникла при создании файла”; getch();exit(1); }
do{cout<<"Введите строку (пустую — для выхода из программы): ”<<”\n";
gets(mystr);
if (strcmp(mystr,"")==0){break;}
strcat (mystr, "\n") ;
/*В конец строки добавим символ-разделитель"\n" */
fputs(mystr, myfile);
/*Строку вводим в файл*/
}while(*mystr!='\n' );
fclose(myfile);
}

Задача

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

Решение
/* В начале подключаем четыре заголовочных файла: iostream.h, stdio.h, stdlib.h, conio.h.*/
int main(){
const int n=256;
char mystr[n];
FILE * myfile= fopen("d:\\Testmy.txt","r");
if ( myfile==NULL)
{ cout<<" ошибка возникла при открытии файла"; getch();exit(1); }
while(!feof(myfile)) {
fgets(mystr,n,myfile);
                            cout<

Для чтения и записи данных любых типов используются функции: fread() и fwrite():

size_t fread(void *ptr, size_t size, size_t n, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t n, FILE *stream);

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

/* В начале подключаем заголовочныe файлы: iostream.h, stdio.h, stdlib.h, conio.h, string.h */
void  main() {
          struct spisok {      char fam[40];
                            int d,m,y;
                            char ad[100];} sp;
          int i,k;           
         FILE *myfile=fopen("d:\\spisok.dat","wb+");
          cout <<"Введите количество записей: "; cin>>k;
          for(i=0;i>sp.d;
                    cout<<" Введите месяц рождения:"; cin>>sp.m;
                    cout<<" Введите год рождения:"; cin>>sp.y;
                    cout<<" Введите адрес:"; gets(sp.ad);
                   fwrite(&sp,sizeof sp,1,myfile);
         }
         fflush(myfile); 
         rewind(myfile);
          i=1;

Язык программирования С++ обеспечивает несколько способов работы с файлами. Рассмотрим способ потока. Поток является некоторым абстрактным понятием, который относится к любому переносу данных (последовательность байтов) от источника к приемнику. Операция записи информации в поток называется включением информации, а чтение информации из потока извлечением. Эти операции выполняются через буфер. Потоки бывают входные (информация заносится в память), выходные (информация считывается из памяти), а также двунаправленные (допускается как чтение информации, так и запись) [1-5].

Для работы с файловыми потоками применяются классы istream и ostream. Эти классы базовые для класса iostream, который реализует двунаправленный поток. Чтобы применить в программе этих классов нужно подключить соответствующие заголовочные файлы.

Преимущества работы с файлами используя поток по сравнению с функциями ввода-вывода — контроль типов и работа с типами пользователя. Недостаток работы с использованием потока — это уменьшение быстродействия программы.

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

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

  1. открытие файла (для записи информации, добавления или чтения);
  2. запись информации в файл или считывание её с файла;
  3. закрытие файла.

При закрытии файл отсоединяется от потока.

Чтобы связать поток с файлом, нужно использовать управляющую структуру (указатель файла), которая имеет тип FILE. Эта структура содержит всю информацию о файле.

Используя FILE, переменная типа указатель файла объявляется следующим образом:

FILE * myfile;

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

FILE *fopen (const char *file_name, const char *file_mode);

Здесь *file_name — это имя файла, перед именем можно указать путь к файлу. Параметр *file_mode определяет режим открытия файла.

Если при выполнении операции открытия файла вышла ошибка, то fopen() вернет NULL, т.е. пустой указатель.

Файл закрывается с помощью функции fclose():

int fclose(FILE *myfile);

Здесь myfile указатель файла.

Cимвола с файла можно считать используя функцию fgetc():

int fgetc(FILE *myfile);

fgetc() возвращает целочисленное значение. Символ находится в младшем разряде. В том случае, если чтение произошло без ошибок, то старший разряд равен нулю. При чтении признака конца файла функция fgetc() вернет значение EOF.

Символ в файл записывается с помощью функции fputc():

int fputc( int сh, FILE *myfile);

Здесь сh — записываемый символ. В файл записывается только младший разряд сh.

Для определения достигнут ли конец файла, необходимо использовать функцию feof():

int feof(FILE *myfile);

При чтении признака конца файла feof() вернет true, а иначе — false.

Задача

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

Решение
/* В начале подключаем четыре заголовочных файла: iostream.h (содержит cin и cout), stdio.h (содержит тип FILE и все функции для работы с файлами), stdlib.h (содержит exit()), conio.h (содержит getch()).*/
void main(){
FILE *inmyfile, *outmyfile;
char mych, FileRead[]="d:\\old.txt", FileWrite[]="d:\\new.txt";
inmyfile = fopen(FileRead,"rb");
outmyfile = fopen(FileWrite,"wb");
if (inmyfile==NULL)
{ cout<<" ошибка возникла при открытии файла"; getch(); exit(1); }
/* Если не удалось открыть файл, то выводим об этом сообщение на экран и выходим из функции main(), т.е. из программы в данном случае */
if (outmyfile==NULL)
{ cout<<" ошибка при создании файла"; getch();exit(1); }
/* Если не удалось создать файл, то также завершаем работу программы  */
/*в следующем цикле происходит копирование файла*/
while(!feof(inmyfile)) { mych = fgetc(inmyfile);
if(!strrchr("0123456789",mych))
fputc(mych,outmyfile);
}
fclose(inmyfile);
fclose(outmyfile);
}

Данные из файла можно считывать и записывать строками. Для этого используются функции fgets() и fputs():

int fputs(const char *mys, FILE *myfilename);
char *fgets(char *mys, int n, FILE *myfilename);

Здесь параметр n — это длина строки, *mys — указатель на строку.

Задача

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

Решение
/* В начале подключаем четыре заголовочных файла: iostream.h, stdio.h, stdlib.h, conio.h.*/
void  main(){
char mystr[256];
FILE * myfile= fopen("d:\\Testmy.txt","w");
if ( myfile==NULL)
{ cout<<” ошибка возникла при создании файла”; getch();exit(1); }
do{cout<<"Введите строку (пустую — для выхода из программы): ”<<”\n";
gets(mystr);
if (strcmp(mystr,"")==0){break;}
strcat (mystr, "\n") ;
/*В конец строки добавим символ-разделитель"\n" */
fputs(mystr, myfile);
/*Строку вводим в файл*/
}while(*mystr!='\n' );
fclose(myfile);
}

Задача

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

Решение
/* В начале подключаем четыре заголовочных файла: iostream.h, stdio.h, stdlib.h, conio.h.*/
int main(){
const int n=256;
char mystr[n];
FILE * myfile= fopen("d:\\Testmy.txt","r");
if ( myfile==NULL)
{ cout<<" ошибка возникла при открытии файла"; getch();exit(1); }
while(!feof(myfile)) {
fgets(mystr,n,myfile);
                            cout<

Для чтения и записи данных любых типов используются функции: fread() и fwrite():

size_t fread(void *ptr, size_t size, size_t n, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t n, FILE *stream);

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

/* В начале подключаем заголовочныe файлы: iostream.h, stdio.h, stdlib.h, conio.h, string.h */
void  main() {
          struct spisok {      char fam[40];
                            int d,m,y;
                            char ad[100];} sp;
          int i,k;           
         FILE *myfile=fopen("d:\\spisok.dat","wb+");
         cout <<"Введите количество записей: "; cin>>k;
         for(i=0;i>sp.d;
                    cout<<" Введите месяц рождения:"; cin>>sp.m;
                    cout<<" Введите год рождения:"; cin>>sp.y;
                    cout<<" Введите адрес:"; gets(sp.ad);
                   fwrite(&sp,sizeof sp,1,myfile);
         }
         fflush(myfile); 
         rewind(myfile);
         i=1;
         cout<<"\n Исходный файл содержит следующие данные: \n";
         while(fread(&sp,sizeof sp,1,myfile)) {
         cout<
Для чтения и записи данных при прямом доступе используется функция fseek(), которая устанавливает указатель файла в нужную позицию:
int fseek(FILE *file_stream, long offset, int whence);

Здесь offset — количество байтов, на которое нужно перенести указатель файла, начиная от позиции whence. Параметр whence может принимать значения SEEK_SET (начало файла), SEEK_CUR (текущая позиция файла), SEEK_END (конец файла).

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

fseek(myfile, 4*sizeof (spisok), SEEK_SET);

Здесь spisok — тип элементов.

Для определения значения указателя текущей позиции в файле нужно использовать функцию ftell():

long int ftell(FILE *file_stream);

Вывод

В работе рассмотрены способы работы с файлами на языке программирования С++. В качестве примера приведены решения некоторых задач. Приведенные программы могут быть использованы при решении задач по файлам.

Список литературы

  1. Вирт Н. Алгоритмы и структуры данных. – М.: Мир, 1989. – 406 с.
  2. Дубров Г.В. Основы программирования на С++. – М.: Конкорд, 1993. – 219 c.
  3. Подбельский В.В. Язык С++: Учебное пособие – 5 изд. – М: Финансы и статистика, 2004. – 560 c.
  4. Хусаинов, И.Г. Решение задач на ЭВМ. Структурное программирование / Стерлитамак: Стерлитамакский филиал БашГУ, 2014. 110 с.
  5. Шилдт Г. С++: базовый курс. 3-е издание. – М.: Издательский дом "Вильямс". 2010. – 624 с.