Файловый ввод/вывод в языке С
Задание 6
- Вывод информации в дополнительный текстовый файл сделайте построчно, и каждую строку запишите в обратном порядке (для рассмотренного примера в три строки).
- Вместо функции putchar() примените printf().
- Вместо функции putc() примените функцию с тем же действием.
- Подготовьте текстовый файл со своей фамилией, инициалами, номером группы, специальности. Выполните чтение из этого файла в обратном порядке и вывести на консоль и запишите в дополнительный текстовый файл с именем compX.txt, где Х – номер компьютера, за которым выполняется лабораторная работа.
Пример 7. Создайте файл последовательного доступа и записать в него информацию, состоящую из целых чисел, строки символов и вещественных чисел. После произведенной записи выведите содержимое файла на консоль и перезапишите в другой файл.
Предположим, что имеются номера ячеек, их имена (например, по фамилии владельца) и определенное количество денег в условных единицах (у. е.).
Для форматированного считывания данных из файла применим библиотечную функцию fscanf().
Программный код решения примера:
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <conio.h> #define MAX 39 // Предполагаемое число символов в имени #define file "D:\\data7.dat" #define file2 "D:\\data77.dat" int main(void) { int number, i = 1, j = 1; // номер ячейки char name[MAX+1]; // имя ячейки (владельца) long double sum; // сумма денег в у.е. FILE *fid, *fid2; if ( fopen_s(&fid, file, "w") ) {fprintf(stdout, "\n\t File could not be opened\n"); printf("\n Press any key: "); _getch(); return 0; } printf("\n Enter through blanks number of a cell,\n a name of the owner and the sum of money.\n \ Type Ctrl+Z to exit at the beginning of a new line: \n\n"); printf(" %3d) ", i); scanf("%d%s%lf", &number, name, &sum); // Запись в файл data7.dat while ( !feof(stdin)) { // stdin - поток с клавиатуры fprintf(fid, " %3d\t %-15s %7.2f\r\n", number, name, sum); printf(" %3d) ", ++i); scanf("%d%s%lf", &number, name, &sum); } fclose(fid); if ( fopen_s(&fid, file, "r") ) { fprintf(stdout, "\n\t File could not be opened\n"); printf("\n Press any key: "); _getch(); return 0; } if ( fopen_s(&fid2, file2, "w") ) { fprintf(stdout, "\n\t File could not be opened\n"); printf("\n Press any key: "); _getch(); return 0; } // Вывод на консоль printf("\n %s\t %s\t\t %5s", "The number of cell", "Name", "Sum"); // Чтение из файла data7.dat fscanf(fid, "%d%s%Lf", &number, name, &sum); fprintf(fid2, "\r\n %s\t\t %s\t\t %5s\r\n", "The number of cell", "Name", "Sum"); i = 1; while ( !feof(fid)) { // пока не конец файла // Вывод на консоль printf("\n %3d\t\t\t %-17s %1.2f", number, name, sum); // Запись в файл data77.dat fprintf(fid2, " %3d) %3d\t\t\t %-17s %1.2f\r\n", i++, number, name, sum); // Чтение из файла data7.dat fscanf(fid, "%d%s%Lf", &number, name, &sum); } fclose(fid); fclose(fid2); printf("\n\n\n Result see the files, \"%s\" and \"%s\"\n", file, file2); printf("\n Press any key: "); _getch(); return 0; }
В программе использована функция feof(), которая проверяет, достигнут ли конец файла, связанного с потоком (указателем на файл) fid.
На рис. 12.11 показан возможный результат выполнения программы.
Следует обратить внимание на прекращение ввода данных с клавиатуры с помощью комбинации клавиш Ctrl+Z.
Задание 7
- Вместо оператора цикла while примените оператор цикла for.
- Отсортируйте записи владельцев ячеек по убыванию величины суммарной денежной суммы.
- Подготовьте форматированный текстовый файл с именем compX, где Х – номер компьютера, за которым выполняется лабораторная работа. Затем информацию из файла выведите на консоль.
Пример 8. Напишите программу пакетной записи в файл произвольного доступа массива данных и вывода этого пакета на консоль.
Для решения примера применим функции fwrite() и fread() для бинарной записи и считывания информации.
Программный код решения примера:
#include <stdio.h> #include <conio.h> #define MAX 20 #define n 5 #define m 4 #define file "D:\\data8.txt" int main(void) { //Матрица 5х4 int mass[MAX][MAX] = { {1,2,3,4}, {5,6,7,8}, {9,10,11,12}, {13,14,15,16}, {17,18,19,20} }; int mass2[MAX][MAX]; // Вспомогательная матрица int i, j; // Массив из 5 указателей char *str[] = { "Brian W. Kernighan", "Dennis M. Ritchie", "Stephen Prata", "Herbert Shildt", "The C Programming Language" }; char *str2[n]; // Вспомогательный массив указателей FILE *fid; if ( fopen_s(&fid, file, "wb") ) { fprintf(stdout, "\n\t File could not be opened\n"); printf("\n Error! Press any key: "); _getch(); return 0; } fwrite(str, sizeof(char), sizeof(str)/sizeof(char), fid); fwrite(mass, sizeof(int), sizeof(mass)/sizeof(int), fid); fclose (fid); if ( fopen_s(&fid, file, "rb") ) { fprintf(stdout, "\n\t File could not be opened\n"); printf("\n Press any key: "); _getch(); return 0; } fread(str2, sizeof(char), sizeof(str)/sizeof(char), fid); fread(mass2, sizeof(int), sizeof(mass2)/sizeof(int), fid); // Чтение элементов из файла printf("\n\t From a file \"%s\": \n\n", file); for (i = 0; i < n; ++i) printf("\t %-15s\n", str2[i]); printf("\n\t Matrix from a file \"%s\":\n", file); for (i = 0; i < n; ++i) { printf("\n\t"); for (j = 0; j < m; ++j) printf(" %3d", mass2[i][j]); } fclose(fid); printf("\n\n\n Press any key: "); _getch(); return 0; }
Функция fwrite() пересылает в файл заданное количество байт начиная с указанного адреса памяти. Данные записываются с того места в файле, которое обозначено указателем позиции файла. Функция fread() пересылает заданное количество байт на места в файле, определенного указателем позиции файла, в массив в памяти, начинающийся с указанного адреса.
В программе пакетная запись информации – набора строк и матрицы целых чисел производится через двоичный поток с помощью функций fwrite(). Чтение информации из двоичного файла осуществляется функцией fread(). Форматы записи обеих функций одинаковый, так как в них требуется определить количество объектов с заданным размером байт, которые определяются функцией sizeof().
Результат выполнения программы показан на рис. 12.12 и на рис. 12.13.
Как видно из рисунков, информация на консоли соответствует исходной информации, а в двоичном файле информация не подлежит непосредственному восприятию.
Примечание. Вид бинарной информации в текстовом файле зависит от установленных шрифтов.
Задание 8
- Запишите двоичную информацию в файлы с расширением .dat, .doc, .bin. Проанализируйте файлы после их открытия.
- Вместо массива указателей примените двухмерный символьный массив необходимой размерности.
- Вместо двухмерного массива целых чисел примените целочисленный указатель.
- Перезапишите информацию из двоичного файла в текстовый файл с именем compX.txt, где Х – номер компьютера, за которым выполняется лабораторная работа.
Контрольные вопросы
- Что может быть файлом в языке С?
- Какие обязательные операции выполняются при нормальной работе с файлами? Какие библиотечные функции при этом используются?
- Как определяется текстовой поток в стандарте языка С?
- Как определяется двоичный поток в стандарте языка С?
- Что определяет собой указатель файла?
- С помощью каких функций языка С осуществляется форматная запись в файл и форматное чтение данных из файла?
- Какая переменная стандартной библиотеки используется для определения стандартного потока вывода на дисплей?
- Какая переменная стандартной библиотеки используется для определения стандартного потока чтения с дисплея?
- Как в языке С кодируется признак конца файла?
- Как в языке С кодируется признак конца строки?
- Что такое файл произвольного доступа?
- Как в языке С осуществляется пакетная запись данных в файл?
- Как осуществляется запись бинарной информации в текстовый файл?
- Как осуществляется чтение бинарной информации из текстового файла?