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

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <conio.h>

const int BUFFSIZE = 10000; // Размер буфера

const int EOQ='.';       // Признак конца фрагмента (End Of Question)

char buff[BUFFSIZE];     // Буфер для текстового фрагмента

bool YesNo (char* msg)   // Меню из двух альтернатив "Да-Нет"

{

puts(msg);      // Вывод сообщения

puts("Please, answer (Y or N)\n");

char c = getch();   // Ждем реакцию

return toupper(c) != 'N'; // Возвращаем результат (согласие или отказ)

}

void ShowError (char* s)   // Сообщение об ошибке и выход

{

printf ("\nError: %s\n",s);

getch();

exit (-1);

}

//========= Функция, сканирующая файл и определяющая позиции всех фрагментов

int Scan (FILE *fp,  // Указатель на структуру типа FILE

    int size,    // Количество текстовых фрагментов

    long pos[])  // Их позиции в файле

{

for (int i=0; i<size; i++) // По всем фрагментам

{

  pos[i] = ftell (fp);     // Отмечаем начало фрагмента

  char c;         // Поиск символа EOQ (Конец фрагмента)

  for (int n=0;  (c=fgetc(fp)) != EOQ && c!=EOF && n<BUFFSIZE;  n++)

   ;

  if (n>=BUFFSIZE)   // Анализ причин завершения цикла

   if (YesNo ("Fragment is too big.  Quit?"))

    exit(-1);

   else

    break;

  else if (c==EOF)

   if (YesNo ("Unexpected end of file.  Quit?"))

    exit(1);

   else

    break;

}

if (i==0)

  ShowError ("Texts are not found");

if (i<size)

  if (YesNo("There are less fragments than was expected. Quit?"))

   exit (1);

  return i;    // Фактически найдено фрагментов

}

//========= Функция, которая ищет и читает один фрагмент

void ReadText (FILE *fp, // Наш файл

         long pos)  // Позиция фрагмента в файле

{

if (fseek (fp, pos, 0)) // Установка позиции

  ShowError ("Текст не найден !");

   //======== Посимвольно передаем фрагмент в буфер

for (char *p=buff; (*p=fgetc(fp)) != EOQ && *p != EOF; p++)

  ;

//======== Устанавливаем признак конца строки текста

if (*p == EOF)    // Если конец файла, то вместо символа EOF пишем 0

  *p = 0;

else        // Если конец фрагмента, то следующий символ д.б.= 0

  *(++p) = 0;

}

void main()

{

char story[] = "After that they both talked and neighbours listened."

      "During the honey-moon she talked and he listened."

      "When they were engaged, he talked and she listened.";

   //========= Пишем в файл весь текст

FILE *fp = fopen("Story.txt","wt");

int len = strlen(story);

fwrite (story, sizeof(char), strlen(story), fp);

fclose(fp);

   //========== Сканируем файл и отмечаем фрагменты (т.е. предложения, т.к. EOQ=='.')

long pos[4];

fp = fopen("Story.txt","rt");

int size = Scan (fp, 4, pos);

printf("\n\n %d fragments found\n\n",size);

getch();

   //=========== Ищем фрагменты и выводим их (в обратном порядке)

for (int i=size-1; i>=0; i--)

{

  ReadText (fp,pos[i]);

  printf("%d. %s\n",size-i,buff);

}

puts("\n\n");

}

Для того, чтобы сработал защитный код, намеренно задан неверный размер массива pos. Исправьте эту ошибку и отладьте программу. Кроме рассмотренных функций, стандартная библиотека stdio.h, имеет много других — для более тонкой работы с файлами. Их описание можно найти в документации.

Управление папками

Папки или директории, наряду с файлами, являются объектами файловой системы Windows. Существует достаточно много функций для управления всеми объектами файловой системы. Мы рассмотрим как можно создавать, удалять директории, а также изменять текущую директорию с помощью нескольких функций библиотеки времи исполнения (С Runtime Library), подключаемых с помощью header-файла <direct.h>.

Задачу в такой постановке «принесла» одна из студенток нашего факультета. Она работала в школе №239 и ее постоянно мучали проблемы, которые создавали «умные» школьники в компьютерном классе. Известно, что люди подвержены повальным увлечениям. Школьников одновременно обуяло желанние написать программу, которая рекурсивно создает на диске пустые папки, вложенные друг в друга. Представьте себе такого Сизифа, открывающего папку с именем «D», в которой есть только один объект — папка с именем «D» и т.д. до тех пор, пока позволяет дисковое пространство. Она попросила написать программу-противоядие, которая уничтожает все вложенные папки.

Это делает вторая часть программы, приведенной ниже. Первая — упрощает тестирование алгоритма и создает вложенные директории, то есть она имитирует действия школьников. Но наш алгоритм все же имеет ограничение, которое определяется способом задания файлового пути (см. _MAX_PATH). Если вы захотите его снять (это опасно), то делайте это сами и не раскрывайте опасные приемы школьникам.

Первая часть программы предлагает создать 10 вложенных папок, начиная с корня диска: “C:\”. Вторая — входит внутрь самой внутренней папки, затем последовательно выходит из вложенных папок и по пути удаляет их.

#include <stdio.h>

#include <direct.h>

#include <string.h>

#include <conio.h>

#include <stdlib.h>

void main()

{

int nDirs = 10;

char path[_MAX_PATH] = "C:\\", dir[_MAX_PATH];

bool bCreated = false;  // Флаг события: папки только что созданы