Вывод и ввод данных в файл с помощью функций библиотеки периода выполнения (C Runtime Library)

Страницы работы

Содержание работы

Файловые операции

В этом разделе, на примере разработки простых консольных приложений, мы поучимся выводить (и вводить) данные в файл с помощью функций библиотеки периода выполнения (C Runtime Library). Библиотека имеет довольно много функций для ввода-вывода как числовых, так и текстовых данных, но надо остановить свой выбор на каком-то их подмножестве и стараться не смешивать функции, прототипы которых описаны в разных файлах заголовков. Наиболее известны функции ввода-вывода, которые описаны в файле stdio.h. Они позволяют работать со стандартными потоками ввода-вывода:

¨  stdin — входной поток, который по умолчанию связан с клавиатурой

¨  stdout — выходной поток, связанный с экраном,

¨  stderr — поток, в который выводятся сообщения об ошибках или исключительных ситуациях (связан с экраном).

Эти потоки по сути являются указателями на специальный тип структур языка С, которые служат для управления вводом-выводом в файл и описаны как FILE *stdin, *stdout, *stderr;. Кроме того, вы можете создать свой поток типа FILE* и, связав его с определенным файлом, вводить или выводить свои данные.

Для начала создайте новый проект консольного приложения. Для этого выберите команду меню: File-New-Project, задайте в поле Location свою папку на диске, доступном для записи, выберите тип проекта Win32 Console Application, введите имя проекта, например, FileOp.

¨  Подключите к проекту новый файл типа C++ Source File (команда меню File-New-File), задайте ему имя, например, такое же, как и имя проекта).

¨  Перейдите в окно редактора (справа) и введите текст программы:

#include <stdio.h>

#include <stdlib.h>

void main()

{

printf ("\n\n Enter the file name: ");

char fn[_MAX_PATH]; // Здесь использована символическая константа _MAX_PATH (См. Help)

gets(fn);           // Ввод строки с клавиатуры (точнее из потока stdin)

FILE *fp = fopen(fn,"wt"); // Пытаемся открыть файл и создать новую структуру типа FILE

if (!fp)          // Если не получилось, то выводим сообщение и уходим

{

  printf("\n Couldn't open %s\n\n",fn);

  exit(-1);        // Аварийное завершение консольного приложения

}

               // Если файл открыт, то пытаемся вывести в него строку текста

char text[] = "\n\n The Miracle of technology";

if (fputs (text,fp) == EOF)    // Если функция вернула EOF, то это - сбой

  printf("\n\n Couldn't write to file\n\n");

else

{               // Если получилось, то сообщаем пользователю

  fputs(text,stdout);       // stdout - это стандартный выходной поток (связан с экраном)

  puts("\n\n Wrote. Ok!\n"); // Вывод в тот же поток stdout (по умолчанию)

}

fclose(fp);         // Закрываем файл (Должно войти в привычку).

}

Запустите на выполнение (Ctrl+F5). Проверьте наличие и содержимое вновь созданного текстового файла другими средствами, например, с помощью самой же студии разработчика. Обратите внимание на разнообразие функций вывода на экран (printf, puts, fputs). На экран можно вывести той же функцией (fputs), что и в файл, указав поток stdout. В заголовке stdio.h даны прототипы функций для работы с файлами. Там же определена специальная структура типа FILE, поля которой содержат системную информацию о файле, например: указатель на буфер обмена, размер буфера, флаги статуса файла и т. д. Пользователь может не знать подробности строения и использования системой этой структуры, но он должен описать переменную типа FILE* и использовать ее при вызове функций, оперирующих с файлами. Мы рекомендуем отыскать эту структуру в stdio.h и проанализировать смысл ее полей. При задании имен файлов удобно пользоваться символической константой _MAX_PATH, которая определена в stdlib.h, и служит для ограничения длины полного файлового пути.

Теперь для практики создадим две внешние (helper) функции для записи и чтения из файла и с их помощью выведем и снова введем информацию. При этом воспользуемся другими функциями (fwrite, fread) ввода-вывода, которые позволяют манипулировать массивами данных произвольного типа.

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <conio.h>

                                  // Наша функция записи в файл

bool WriteToFile (char* sText, char* sFileName)

{

printf ("\n\n Enter the file name: ");

gets(sFileName);

FILE *fp = fopen(sFileName,"wt");

if (!fp)

  return false;  // Возвращаем результат (неудача)

//==== sText - начало массива,

   //==== sizeof(char) - размер одного элемента,

   //==== strlen(sText) - количество элементов

int nItems = fwrite (sText, sizeof(char), strlen(sText), fp);

printf ("\n\n Wrote %d items\n",nItems);

fclose(fp);

return true;    // Возвращаем результат (успех)

}

                                  // Наша функция чтения из файла

bool ReadFromFile (char* sText, int size, char* sFileName)

{

FILE *fp;

if ((fp = fopen(sFileName,"rt"))==NULL)

  return false;

int nItems = fread (sText, sizeof(char), size,fp);

printf ("\n\n %d items have been read\n\n",nItems);

fclose(fp);

return true;

}

void main()

{

        // Этот текст мы запишем и снова прочтем

char poem[] =

      "It's not learning, grace, nor gear,\n"

      "Nor easy meat and drink,\n"

      "But bitter pinch of pain and fear\n"

      "That makes creation think.\n"

      "\t - R. Kipling.\n\n";

char sFileName[_MAX_PATH];

//============= Пишем в файл ================//

bool bResult = WriteToFile(poem, sFileName);

if ( !bResult )

{

  printf("\n Couldn't write to file %s\n\n",sFileName);

  exit(-1);

}

//============ Предлагаем прочесть его =============//

printf ("\n\n File name: %s.   Shall we read it? (Y/N)\n", sFileName);

if (toupper(getch())=='N')     // Ждем реакцию (getch)

{

  printf("\n Bye\n\n");         // В случае отказа уходим

  exit(-1);

}

for (int i=0; poem[i]; i++)    // Стираем текст перед тем, как прочесть

  poem[i] = ' ';

//============ Читаем текст из файла =============//

bResult = ReadFromFile (poem, strlen(poem), sFileName);

if (!bResult)

  printf("\n Couldn't read from file %s\n\n",sFileName);

else

  puts(poem);               // Выводим то, что прочли

}

При анализе кода попробуйте объяснить как работает механизм передачи формальных и фактических параметров при вызове функций WriteToFile и ReadFromFile.

Посимвольное чтение

Рассмотрим актуальную некогда задачу преобразования текстового файла из альтернативной кодировки (DOS-кодировки) в кодировку ANSI (Windows-кодировку). Альтернативную кодировку можно увидеть, если открыть Windows-утилиту Character Map и выбрать шрифт Terminal. Обратите внимание на местоположение русских букв в этой таблице. Они следуют с разрывом (между буквами 'п' и 'р'). Сравните эту кодировку с Windows-кодировкой, выбрав какой-либо другой шрифт, например, Times New Roman Cyr. Здесь символы следуют непрерывно и занимают самый низ таблицы. Теперь вам станет ясен алгоритм преобразования кодов:

¨  Если код символа находится в диапазоне между кодом буквы 'А' (128) и кодом буквы 'п' (175), то его надо сдвинуть на 64 единицы.

¨  Если код — в диапазоне между 'р' (224) и 'я' (240), то его надо сдвинуть на 16 единиц.

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

Информация о работе