Практическая часть. Пример 1. Напишите программу заполнения матрицы размера n×m нечетными целыми числами с выводом результата на консоль и в текстовый файл

Пример 1. Напишите программу заполнения матрицы размера n×m нечетными целыми числами с выводом результата на консоль и в текстовый файл. Размеры матрицы и начальное нечетное число задаются пользователем с клавиатуры.

Программный код решения примера:

#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include <conio.h>#include <stdlib.h> int main(void) {int i, j, x, xi, n, m, *matr;FILE *fid;char str[] = "D:\\data.txt"; // месторасположение файлаif ((fid = fopen(str, "w")) == NULL){ printf("\n\t The file could not be opened.\n "); printf("\n Press any key: ");_getch(); return 0; } printf("\n\t Enter the number of lines: "); scanf_s("%d", &n);printf("\t Enter the number of columns: "); scanf_s("%d", &m);printf("\t Enter the odd number: "); scanf_s("%d", &x);xi = x; matr = (int *)calloc(n*m, sizeof(int));// Заполнение матрицы целыми числамиfor (i = 0; i < n; ++i)for (j = 0; j < m; ++j){matr[i*m + j] = x; x += 2; } printf("\n\t Matrix (%d x %d), initial number: %d\n", n, m, xi);fprintf(fid, "\r\n\t Matrix (%d x %d), initial number: %d\r\n", n, m, xi);for (i = 0; i < n; ++i){ printf("\n "); fprintf(fid, "\r\n "); for (j = 0; j < m; ++j){printf("%5d", matr[i*m + j]); fprintf(fid, "%5d", matr[i*m + j]); }} fclose(fid);printf("\n\n Result of record look in file %s\n", str); printf("\n Press any key: ");_getch();return 0; }

В программу включена препроцессорная директива #define... для устранения предупреждения о ненадежной работе функции fopen() в Visual Studio 2008.

Возможный результат выполнения программы показан на рис. 12.1.


Рис. 13.1. Заполнение матрицы нечетными числами

Текстовый файл с заполненной матрицей показан на рис. 13.2.

Рис. 13.2. Матрица нечетных чисел в текстовом файле

Примечание. В текстовом файле следует использовать моноширинный (равноширинный) шрифт, например, Courier New.

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

В качестве строки возьмем "hello, world". Для посимвольной записи в файл используем функции putc() и fputc(), которые реализованы для сохранения совместимости со старыми версиями языка С. Для прекращения чтения символов с клавиатуры используем точку, т.е. '.'.

Программный код решения примера:

#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include <conio.h> int main(void){char ch; FILE *f_in, *f_out;char str[] = "X:\\data.txt"; // Файл записиchar str2[] = "X:\\data2.txt";// Файл перезаписи if ((f_in = fopen(str, "w")) == NULL){ printf("\n\t The file could not be opened.\n "); printf("\n Press any key: ");_getch(); return 0;} printf("\n Enter the characters by pressing Enter and exit point:\n\n> "); while ((ch = getchar())!= '.'){ printf(" "); fputc(ch, f_in);}fclose(f_in); if ((f_in = fopen(str, "r")) == NULL){ printf("\n\t The file could not be opened.\n "); printf("\n Press any key: ");_getch(); return 0; } if ((f_out = fopen(str2, "w")) == NULL){ printf("\n\t The file could not be opened.\n "); printf("\n Press any key: ");_getch(); return 0;} while((ch = getc(f_in))!= EOF) putc(ch, f_out); fclose(f_in);fclose(f_out); printf("\n\n Result of record look in file %s\n", str);printf(" Result of rewriting look in file %s\n", str2); printf("\n Press any key: ");_getch();return 0; }

В программе сначала открывается файл data.txt для записи в него символов, затем он закрывается. После этот же файл открывается для считывания записанных символов с целью записи их в другой файл, под именем data2.txt. Всякий раз производится проверка возможности открытия файлов. Запись символов в текстовый файл выполняется с помощью функций putc() и fputc(). Считывание символов из файла осуществляется с помощью функции getc().

В среде Visual Studio стандартная функция fopen() языка С вызывает предупреждение при компиляции программы. Для устранения предупреждений при компиляции в программу включена препроцессорная директива #define_CRT_SECURE_NO_WARNINGS.

Результат выполнения программы показан на рис. 13.3.

Рис. 13.3. Консольный ввод символов для записи в файл

Текстовые файлы с введенной таким образом последовательностью символо показаны на рис. 13.4. и рис. 13.5

Рис. 13.4. Последовательность символов в текстовом файле data.txt

Рис. 13.5. Последовательность символов в текстовом файле data2.txt

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

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

============================================= THE_____________________________________________ C _____________________________________________ PROGRAMMING LANGUAGE============================================= Second Edition BRIAN W. KERIGHAN DENNIS M. RITCHIE AT & T Bell Laboratories Murray Hill, New Jersey Prentice Hall PTR, Upper Saddle River, New Jersey 07458_________________________________________________________

Файлу, из которого будет считываться информация, присвоим имя data3.txt. Файлу, куда будет записываться информация, присвоим имя data33.txt.

Программный код решения примера:

#include <stdio.h>#include <conio.h> int main(void){char str[255+1];char data3[] = "X:\\data3.txt";char data33[] = "X:\\data33.txt";FILE *fid, *fid2;errno_t err; if ((fopen_s(&fid, "X:\\data3.txt", "r")) || (err = fopen_s(&fid2, "X:\\data33.txt", "w"))!= 0){ printf("\n\t The file could not be opened.\n ");printf("\n Press any key: "); _getch(); return 0; } while (fgets(str, 255, fid)!= NULL) // Чтение из data3.txt{fputs(str, stdout); // Вывод на консольfputs(str, fid2); // Запись в файл data33.txt} fclose(fid); fclose(fid2); printf(" Read the information was produced from a file %s\n", data3); printf(" Recorded information has been made to the file %s\n", data33); printf("\n Press any key: "); _getch(); return 0; }

В программе с помощью логического условия ИЛИ (||) производится проверка корректности открытия файла data3.txt для чтения и проверка открытия файла data33.txt для записи. Вместо функции fopen() используется функция fopen_s(), которая применяется в MS Visual Studio.

Функция fgets() считывает строки из файла, на который имеется файловый указатель *fid, записывает их в символьный массив str[256]. Одно поле функции fgets() используется для определения количества считываемых символов с учетом символа завершения строки.

Первая функция fputs() используется для вывода информации на консоль с помощью определения стандартного выходного потока stdout, который указывает на "обычное" средство вывода – дисплей. Вторая функция fputs() выводит символьный массив str[] в файл data33.txt с помощью файлового указателя *fid2. Вывод на дисплей и запись в файл будет осуществляться до тех пор, пока при чтении из файла data3.txt не обнаружится признак конца файла, т.е. NULL. Проверку можно выполнять также по числу считанных символов, а именно n –1, т.е. в данном случае 255 символов из 256.

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

Рис. 13.6. Консольный вывод содержимого текстового файла

Результат записи информации в текстовый файл показан на рис. 13.7.

Рис. 13.7. Результат записи текстовой информации в текстовый файл

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

Для решения примера используем функции fprintf(), fgets(), atoi(), fscanf().

Программный код решения примера:

#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include <conio.h>#include <stdlib.h> #define n 4 // Число строк матрицы#define m 3 // Число столбцов матрицы#define N 123 // Число считываемых строк из текстового файла int main(void) { int i, j = 0; int A[n*m] = {1,2,3,4,5,6,7,8,9,10,11,12}; int B[n*m]; FILE *fid; char *str[] = {"aza","baza","qwerty"}; char str2[N][80]; // Буферный массив // Обнуление массива B[n*m] for (i = 0; i < n*m; ++i) B[i] = 0; if ((fid = fopen("X:\\data4.txt", "w")) == NULL){printf("\n\t The file could not be opened.\n ");printf("\n Press any key: "); _getch(); return 0; } // Запись в файл data4.txtfprintf(fid, "\n\t The lines are:\n");for (i = 0; i < m; ++i) fprintf(fid,"\t %s\n", str[i]); for (i = 0; i < n*m; ++i) fprintf(fid, " %3d", A[i]); fclose(fid); printf("\n\t From file \"data4.txt\":\n");if ((fid = fopen("X:\\data4.txt", "r")) == NULL){printf("\n\t The file could not be opened.\n ");printf("\n Press any key: "); _getch(); return 0; } // Чтение из файла data4.txtfor (i = 0; (fgets(str2[i], 80, fid)!= NULL) && (i < N); ++i) printf(" %s",str2[i]);fclose(fid); if ((fid = fopen("X:\\data4.txt", "r")) == NULL){printf("\n\t Error! You can not open the file \n ");printf("\n Press any key: "); _getch(); return 0; }// Повторное чтение из файла data4.txtfor (i = 0; fscanf (fid, "%s", str2[i])!= EOF; ++i) if (atoi(str2[i])){ B[j] = atoi(str2[i]); ++j; } fclose(fid); printf("\n\n\t The reconfigured array:\n");for (i = 0; i < n; ++i) {printf("\n\t");for (j = 0; j < m; ++j)printf("%5d", B[i*m+j]); } printf("\n\n Press any key: ");_getch(); return 0; }

Для форматированной записи в текстовый файл и чтения из файла применены массивы указателей *str[], str2[123][80]. Чтение из файла одномерного массива целых чисел выполняется с помощью функции atoi(), значения целых чисел заносятся сначала в одномерный массив B[n*m]. После закрытия файла data4.txt одномерный массив B[n*m] выводится на консоль в виде двухмерной матрицы размера 4×3. Форматированная запись строк и одномерного массива в файл data4.txt производится с помощью функции fprintf(). Первое чтение информации из текстового файла производится с помощью функции fgets(), что позволяет практически точно копировать расположение строк текстового файла на консоль (дисплей). Функция fscanf() используется для форматированного чтения информации из текста с последующим выделением целых чисел с помощью функции atoi().

Возможный результат выполнения программы показан на рис. 13.8.

Рис. 13.8. Содержимое текстового файла и преобразованного массива

Пример 5. Напишите программу добавления слов в текстовый файл с контролем на консоли.

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

Для программного решения примера используем функции файлового ввода/вывода 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[] = "X:\\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.txtwhile (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, "X:\\data5.txt","a+");

Тогда проверку на открытие файла следует изменить, например:

if (fopen_s(&fid, "X:\\data5.txt","a+")){fprintf(stdout, "\n\t Ошибка! Не удается открыть файл \"data5.txt\".\n ");printf("\n Нажмите любую клавишу: ");_getch(); return -1; }

Если файл data5.txt сохранить, то при последующих выполнениях программы в этот файл будут дописывать данные. Это обеспечивает режим "a+" функции fopen().

Возможный результат выполнения программы показан на рис. 13.9.

Рис. 13.9. Пример записи в файл и чтения из файла

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

Для решения примера используем функции fseek() и ftell().

Программный код решения примера:

#include <stdio.h>#include <conio.h> #define MAX 79#define file "X:\\data6.txt" // запись в прямом порядке#define file2 "X:\\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.txtwhile (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 forputchar('\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() имеет следующую форматную запись:

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. Следующая итерация цикла выводит программу на предпоследний символ файла, который она печатает и записывает в новый файл. Этот процесс продолжается до тех пор, пока программа не выйдет на первый символ файла и не распечатает его (и запишет в файл).

Возможные результаты выполнения программы показаны на рис. 13.10-рис. 13.12.

Рис. 13.10. Результат обратного считывания информации из файла

Рис. 13.11. Результат записи информации в файл

Рис. 13.12. Результат записи информации в файл в обратном порядке

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

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

Для форматированного считывания данных из файла применим библиотечную функцию fscanf().

Программный код решения примера:

#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include <conio.h> #define MAX 39 // Предполагаемое число символов в имени#define file "X:\\data7.dat"#define file2 "X:\\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.datwhile (!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.datfscanf(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.datfscanf(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.

На рис. 13.13 показан возможный результат выполнения программы.

Рис. 13.13. Консольный вывод содержимого файла

Следует обратить внимание на прекращение ввода данных с клавиатуры с помощью комбинации клавиш Ctrl+Z.

Пример 8. Напишите программу пакетной записи в файл произвольного доступа массива данных и вывода этого пакета на консоль.

Для решения примера применим функции fwrite() и fread() для бинарной записи и считывания информации.

Программный код решения примера:

#include <stdio.h>#include <conio.h> #define MAX 20#define n 5#define m 4#define file "X:\\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().

Результат выполнения программы показан на рис. 13.14 и на рис. 13.15.

Рис. 13.14. Результат чтения из файла бинарной информации

Рис. 13.15. Результат записи в текстовый файл бинарной информации

Как видно из рисунков, информация на консоли соответствует исходной информации, а в двоичном файле информация не подлежит непосредственному восприятию.

Примечание. Вид бинарной информации в текстовом файле зависит от установленных шрифтов.

Контрольные вопросы

1. Что может быть файлом в языке С?

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

3. Как определяется текстовой поток в стандарте языка С?

4. Как определяется двоичный поток в стандарте языка С?

5. Что определяет собой указатель файла?

6. С помощью каких функций языка С осуществляется форматная запись в файл и форматное чтение данных из файла?

7. Какая переменная стандартной библиотеки используется для определения стандартного потока вывода на дисплей?

8. Какая переменная стандартной библиотеки используется для определения стандартного потока чтения с дисплея?

9. Как в языке С кодируется признак конца файла?

10. Как в языке С кодируется признак конца строки?

11. Что такое файл произвольного доступа?

12. Как в языке С осуществляется пакетная запись данных в файл?

13. Как осуществляется запись бинарной информации в текстовый файл?

14. Как осуществляется чтение бинарной информации из текстового файла?


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: