Программная инженерия 1 курс / 2 семестр / lab3 / report_lab3
.docxМИНОБРНАУКИ РОССИИ
Санкт-Петербургский государственный
электротехнический университет
«ЛЭТИ» им. В.И. Ульянова (Ленина)
Кафедра МОЭВМ
отчет
по лабораторно-практической работе №3
по дисциплине «Программирование»
Тема: Обход файловой системы
Студент гр. 7303 |
Овчинников С.М. |
|
Преподаватель |
Берленко Т.А. |
|
Санкт-Петербург
2018
Цель работы.
Дана некоторая корневая директория, в которой может находиться некоторое количество папок, в том числе вложенных. В этих папках хранятся некоторые текстовые файлы, имеющие имя вида <filename>.txt. В качестве имени файла используется символ латинского алфавита.
На вход программе подается строка. Требуется найти и вывести последовательность полных путей файлов, имена которых образуют эту строку.
Входная строка:
HeLlO
Правильный ответ:
hello_world_test/asdfgh/mkoipu/H.txt
hello_world_test/qwerty/e.txt
hello_world_test/qwerty/qwert/L.txt
hello_world_test/asdfgh/l.txt
hello_world_test/asdfgh/O.txt
-
Программа должна принимать на вход количество слов и слова, разделенные пробелами.
-
Регистрозависимость
-
Могут встречаться файлы, в имени которых есть несколько букв и эти файлы использовать нельзя.
Ход работы.
Был создан файл main.c
#include <stdio.h>
#include <dirent.h>
#include <string.h>
#define LENGTH 100
FILE* result;
int break_flag;
void print_file(){
FILE* file = fopen("./result.txt","r");
if( !file ) return;
char s[100];
while( fgets(s, 100, file) ){
printf("%s", s);
}
fclose(file);
}
void write_file(char* str){
if(!result) return;
strcat(str,"\n");
fputs( str, result );
}
void list_dir(char* startdir, char sign){
if(break_flag) return;
char nextdir[200] = {0};
strcpy( nextdir, startdir );
DIR* dir = opendir( startdir );
if( !dir ) return;
struct dirent* de = readdir( dir );
while( de){
if(strcmp(de->d_name, ".") != 0
&& strcmp(de->d_name, "..") != 0){
int len = strlen( nextdir );
strcat( nextdir, "/" );
strcat( nextdir, de->d_name );
if( sign == de->d_name[0]
&& strlen(de->d_name) == 5
&& strstr(de->d_name,".txt")
&& de->d_type == DT_REG){
write_file(nextdir);
closedir(dir);
break_flag = 1;
return;
}
if( de->d_type == DT_DIR ){
list_dir( nextdir, sign );
nextdir[len] = '\0';
}
}
de = readdir(dir);
}
closedir(dir);
}
int main(){
char str[LENGTH];
scanf("%s",str);
result = fopen("result.txt","w");
int i;
for(i = 0; i<strlen(str);i++){
if (strchr(str, str[i]) -str == i){
break_flag = 0;
list_dir("./tmp", str[i]);
}
}
fclose(result);
print_file();
return 0;
}
В начале работы программы объявляется указатель на поток result: FILE * result и переменная-флаг break_flag типа int.
Далее описываются две функции для работы с файлом result.txt:
-
write_file – дописывает строку к содержимому файла
-
print_file – распечатывает файл в консоль
В файле main.c содержится главная функция main. В ней объявляется массив str типа char. Функция scanf считывает str как строковую переменную. Функция fopen с параметром “w” создаёт файл result.txt для записи. Затем в цикле for пока не заканчивается строка str, если символ из str ещё не встречался, break_flag инициализируется нулём, вызывается функция list_dir, которой в качестве аргументов передаются этот символ и исходная директория.
Файл закрывается. Вызывается функция print_file. Программа завершается.
Функция list_dir в качестве аргументов принимает путь startdir (массив типа char) и символ sign (типа char), который она будет искать в названии файлов. В list_dir объявляется указатель на структуру DIR dir, функция opendir, которой передаётся path в качестве аргумента, присваивает указатель на поток каталога, соответствующий пути path. Если нужный файл был уже найден, то директория тут же закрывается и функция для работы с ней завершается. Затем объявляется указатель на структуру dirent de. В цикле while пока функция readdir не вернёт NULL, то есть всё содержимое dir просмотрено, если каталог не текущий(.) и не предыдущий(..), то создаём новый путь nextdir(переменная типа char*) равный startdir плюс de->d_name. Затем если de является обычным файлом, формата txt, длиной 5 символов и первый символ в его названии совпадает с sign, записываем путь к этому файлу в result.txt с помощью функции write_file. Переменной break_flag присваивается 1, закрывается директория, завершается функция для работы с ней. Если de является каталогом, то вызываем для этого каталога функцию list_dir.
Выводы.
В ходе лабораторной работы были изучены функции для работы с файлами и каталогами в Си, был усвоен рекурсивный метод обхода файловой системы, был создан файл main.c, исполнивший свою задачу – создание файла, в который необходимо записать пути ко всем файлам, состоящим из одной буквы латинского алфавита, встречающимся в ключевом слове, и расширения .txt.