Файловый ввод/вывод в языке С
Задание 4
- Для вывода информации из текстового файла поочередно используйте функции fgets() и fscanf().
- Инициализацию массива А выполните как инициализацию двухмерной матрицы с возможными сочетаниями числа строк и столбцов.
- В качестве строк разной длины используйте свою фамилию, имя, специальность и номер учебной группы.
- Массивы чисел определите как вещественные.
- Размерность массива задайте с клавиатуры и заполните его натуральными числами по строкам. Предусмотрите проверку возможности преобразования одномерного массива в двухмерный массив. Если возможно преобразование одномерного массив, то выполните вывод двухмерного массива в текстовый файл с именем compX.txt, где Х – номер компьютера, за которым выполняется лабораторная работа.
Пример 5. Напишите программу добавления слов в текстовый файл с контролем на консоли [9].
В текстовый файл запишем название книги и авторов [3]. После будем добавлять слова, символы и т.д.
Для программного решения примера используем функции файлового ввода/вывода fprintf(), fgets() и rewind(). Кроме того, подключим библиотеку locale.h и объявим прототип функции, что позволит использовать шрифты русского алфавита:>
#include <locale.h>
setlocale( LC_ALL, "Russian");или
setlocale( LC_ALL, ".1251");//кодовая страница Windows–1251
Программный код решения примера:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <conio.h>
#include <locale.h>
#define MAX 40
int main(void) {
FILE *fid;
char words[MAX+1];
char str_name[] = "D:\\data5.txt";
// Прототип функции поддержки русских шрифтов
setlocale( LC_ALL, "Russian");
// setlocale( LC_ALL, ".1251");
if ((fid = fopen(str_name, "a+")) == NULL)
{fprintf(stdout, "\n\t Файл не может быть открыт \"%s\".\n ", str_name);
printf("\n Нажмите любую клавишу: ");
_getch(); return -1; }
printf("\n\t Введите слова для включения их в файл \"%s\"\n\t\
и нажмите клавишу Enter в начале строки для завершения ввода\n\t: ", str_name);
// Запись в файл data5.txt
while (gets_s(words, MAX) != NULL && words[0] != '\0')
{printf("\t: "); fprintf(fid," %s\n", words); }
puts("\t Содержимое файла:");
// Устанавливает указатель текущей позиции в начало файла
rewind(fid);
// Сканирование файла
while (fgets(words, MAX, fid) != '\0')
printf("\t%s", words);
if (fclose(fid) != 0)
fprintf(stderr, "\n\t Ошибка при закрытии файла \"%s\"\n", str_name);
printf("\n\n Нажмите любую клавишу (Press any key): ");
_getch();
return 0;
}В программе введены две проверки: на открытие файла if (... == NULL) и на закрытие файла if (... != 0). Эти проверки позволяют исключить аварийный выход из программы. Использование в функции форматного вывода fprintf() ключевого слова stdout позволяет выводить сообщения на консоль – дисплей пользователя.
Вместо стандартной функции gets() использована функция gets_s(), которую поддерживает MS Visual Studio. При работе в MS Visual Studio с функцией gets() появляются предупреждения (которыми в общем случае можно пренебречь). Предупреждения возникают и при работе с функцией fopen(). Вместо нее можно использовать fopen_s() в следующем формате записи:
fopen_s(&fid, "D:\\data5.txt","a+");
Тогда проверку на открытие файла следует изменить, например:
if (fopen_s(&fid, "D:\\data5.txt","a+"))
{fprintf(stdout, "\n\t Ошибка! Не удается открыть файл \"data5.txt\".\n ");
printf("\n Нажмите любую клавишу: ");
_getch(); return -1; }Если файл data5.txt сохранить, то при последующих выполнениях программы в этот файл будут дописывать данные. Это обеспечивает режим "a+" функции fopen().
Возможный результат выполнения программы показан на рис. 12.7.
Задание 5
- В программу при записи в файл и чтения из файла введите свою фамилию, имя, отчество, курс обучения, специальность.
- В программе используйте функцию fopen_s() вместо функции fopen(). Отметьте результат компиляции.
- В программу вместо функции fgets() включите функцию fscanf(). Отметьте результат записи и чтения нескольких строк, состоящих из нескольких слов.
Примечание. Для данной программы формат записи функции fscanf():
fscanf(fid, "%s", words);
Пример 6. Напишите программу записи в файл нескольких строк и отображения содержимого файла в обратном порядке, как на консоли, так и в другом текстовом файле.
Для решения примера используем функции fseek() и ftell().
Программный код решения примера:
#include <stdio.h>
#include <conio.h>
#define MAX 79
#define file "D:\\data6.txt" // запись в прямом порядке
#define file2 "D:\\data66.txt" // запись в обратном порядке
int main(void) {
char ch, str[MAX+1];
long n, m;
FILE *fid, *fid2;
if ( fopen_s(&fid, file, "w") ) {
fprintf(stdout, "\n\t The file could not be opened.\n ");
printf("\nPress any key: ");
_getch(); return 0; }
printf("\n\t Enter a few lines and press Enter to complete before the new line\n\t: ");
// Запись в файл data6.txt
while (gets_s(str, MAX) != NULL && str[0] != '\0')
{ printf("\t: "); fprintf(fid," %s\n", str); }
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; }
//Переход в конец файла
fseek(fid, 0L, SEEK_END);
m = ftell(fid);
for (n = 1L; n <= m; n++) {
fseek(fid, -n, SEEK_END);
ch = getc(fid);
if (ch != '\n') {
printf(" "); putchar(ch);
fprintf(fid2, " "); putc(ch, fid2); }
} // End for
putchar('\n');
fclose(fid);
fprintf(fid2, "%c", '\n');
fclose(fid2);
printf("\n Result see the files, \"%s\" and \"%s\"\n", file, file2);
printf("\n Press any key: ");
_getch();
return 0;
}Работу функций fseek() и ftell() опишем в соответствии с [9].
Функция fseek() имеет следующую форматную запись:
fseek(fid, 0L, SEEK_END);
Она определяет позицию со смещением в 0 байт от конца файла (именованная константа SEEK_END ). Суффикс L означает тип long int.
Строка с функцией ftell() определяет количество байтов от начала до конца указанного файла. Это количество байтов записывается в переменную m:
m = ftell(fid);
Рассмотрим следующий программный цикл:
for (n = 1L; n <= m; n++) {
fseek(fid, -n, SEEK_END);
ch = getc(fid);
if (ch != '\n')
{ printf(" "); putchar(ch);
fprintf(fid2, " "); putc(ch, fid2); }
} // End forПервое выполнение цикла выводит программу на первый символ перед концом файла. Затем программа печатает этот символ на консоль и записывает в новый файл с именем data66.txt. Следующая итерация цикла выводит программу на предпоследний символ файла, который она печатает и записывает в новый файл. Этот процесс продолжается до тех пор, пока программа не выйдет на первый символ файла и не распечатает его (и запишет в файл).
Возможные результаты выполнения программы показаны на рис. 12.8- рис. 12.9– рис. 12.10.


