puts("\nCreate and delete dirs example\n"
"\nShall we create 10 nested dirs in C:\\? (Y/N)\n");
if (toupper(getch()) == 'Y') // Ждем ответ и приводим его к верхнему регистру
{
puts("\n\tEnter the dir name to create:\n");
gets(dir);
if (strlen(dir) != 0)
{
_chdir("C:\\"); // Начинаем с корня
strcat (path, dir); // Наращиваем файловый путь
while (nDirs--)
{
if (_mkdir(path) == -1) // Создаем папку
{
puts("\nCould not create this dir\n");
break;
}
strcat (path, "\\");
strcat (path, dir); // Наращиваем файловый путь
_chdir(dir);
}
_chdir("C:\\");
bCreated = true;
}
}
//===== Вторая (полезная) часть программы
if (!bCreated)
{
puts("\n\tEnter the dirs name to remove:\n");
gets(dir);
if (!strlen(dir))
return;
//=== По умолчанию поиск начнется с текущей директории, которая определяется
//=== местом запуска программы. Его выбирает пострадавший
puts("\nShall we start from C:\\? (Y/N)\n");
if (toupper(getch()) == 'Y')
_chdir("C:\\");
}
//======= Входим внутрь (эта процедура зависит от числа созданных папок)
for (nDirs=0; !_chdir(dir); nDirs++)
;
if (nDirs==0)
{
printf("\n\n %s not found\n\n",dir);
return;
}
//======= Выводим содержимое самой внутренней папки
fflush(stdin);
system ("dir\n"); // Это просто команда DOS
printf("\n\n %d dirs opened\n\n Should we remove them?\n",nDirs);
if (toupper(getch()) != 'Y')
return;
for (int i=0; i<nDirs; i++)
{
_chdir(".."); // Выходим наверх и пытаемся удалить папку
if (_rmdir(dir) == -1)
{
printf("\n%s could not be removed\n\n",dir);
break;
}
else
printf("\nRemoving %s",dir);
}
printf ("\n%d dirs were removed\n\n", i);
}
Задание преследует цель выработать навык работы с динамическими массивами элементов стандартных типов. Дополнительно вы должны поупражняться в использовании файловых операций, рассмотренных в этом разделе. Смысл задания — моделирование отдельных функций синтаксического анализатора.
Условие задания таково:
¨ Пользователь вводит с клавиатуры произвольный текст, завершая его вводом символа «конец файла» (Ctrl+Z).
¨ Отдельный модуль программы размещает текст в буфере и затем записывает его в файл.
¨ Другой модуль подсчитывает количество слов (точнее лексем) nWords во введенном тексте. Разделителями будем считать множество символов: { '\n', '\t', ' '}.
¨ Далее следует отвести память (размером nWords) под динамический массив указателей на тип char, и вызвать модуль, который заполнит этот массив адресами начал слов (лексем) в буфере.
¨ Следует создать еще один динамический массив элементов типа int, в котором пользователь задаст порядок вывода на экран слов из буфера.
¨ После этого надо дать возможность пользователю ввести желаемый порядок и вывести отдельные слова (лексемы) в этом порядке.
Тем, кому это задание кажется слишком простым, предложим оттдельно подсчитать количество лексем, являющихся числовыми данными (например, 2 или 1.0е-3), и вывести их на экран. Кроме того, можно расширить множество символов, разделяющих лексемы.
¨ Для практики задайте новый тип данных typedef unsigned int uint;
¨ Функция подсчета количества слов может иметь примерно такую структуру:
uint CountWords()
{
bool was, is; // Флаги событий: "Был разделитель", "Текущий символ - разделитель"
uint nWords, i;
char c;
//========== Пока следуют обычные символы (не разделители), продолжаем сканировать буфер
for (uint i=num=0, was=true; (c=buf[i])!=0 && c!=EOF; i++)
{
// Определяем флаги и увелиличиваем счетчик слов (если найден разделитель
}
printf ("\nFound %d words\n", num);
return num; // Возвращаем количество слов
}
¨ При работе с массивом указателей вспомните, что массив задается как адрес его начала, то есть массив — это уже указатель. Поэтому динамический массив указателей должен иметь тип адреса адресов символов (или char**).
¨ При реализации вывода отдельных слов, вычленяемых из текста, помните, что символьная строка в языке С (и С++) должна заканчиваться символом с кодом '\0', который надо как-то синтезировать.
¨ При посимвольном вводе текста надо учесть то, что не все функции ввода могут определить факт поступления символа «конец файла» (Ctrl+Z). Советуем воспользоваться функцией getchar().
¨ При поиске целых чисел можно пользоваться функцией strtol (string to long), которая пытается преобразовать последовательность символов в число типа long. Параметры смотрите в Help. Алгоритм ее использования выглядит примерно так:
//====== pStop будет указывать на символ, который остановил сканирование строки (то есть не число)
char *stop, word[] = "24 some text";
char *p = word; // p должно указывать на начало строки
long n = strtol (p, &stop, 0); // Попытка преобразовать строку в число
if (*stop != *p) // Если сканирование продвинулось, то число найдено
printf ("\nInteger %d found\n", n);
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.