2017-02-18 32 views
0

Я пытаюсь показать, какая папка содержит в качестве вывода. Когда я запускаю эту программу на своем жестком диске через 1-2 минуты, она падает, а также сбойная часть работает нормально. Я не знаю, как я могу это предотвратить. Может кто-нибудь мне помочь ?Отображение содержимого папки в c - Ошибка времени выполнения

#include <string.h> 
#include <stdio.h> 
#include <dirent.h> 

void showingFiles(DIR *, char *); 

int main(void) { 
    DIR *folder; 
    char path[350]; 

    sprintf(path, "."); 
    folder = opendir(path); 
    showingFiles(folder, path); 
    closedir(folder); 
    printf("\n\nEnter a key to close this program "); 
    getch(); 
    return 0; 
} 

void showingFiles(DIR *currentFolder, char *path){ 
    struct dirent *nextFile; 
    DIR *subFolder; 
    char copyPath[350]; 
    strcpy(copyPath, path); 
    while ((nextFile = readdir(currentFolder)) != NULL) { 
     sprintf(copyPath, "%s//%s", path, nextFile->d_name); 
     printf("%s\n", (*nextFile).d_name); 
     if ((strcmp(nextFile->d_name, "..")) && 
      strcmp(nextFile->d_name ,".") && 
      (subFolder = opendir(copyPath)) != NULL) { 
      deletingFiles(subFolder, copyPath); 
     } 
    } 
    closedir(currentFolder); 
} 
+0

Ваши средства отладки могут. Мы ожидаем * конкретного * вопроса, ничего подобного «это не работает, помогите мне исправить». См. [Как спросить] (http://stackoverflow.com/help/how-to-ask), чтобы сформулировать хорошие вопросы. – Downvoter

+0

ладно, спасибо человеку, я проверю его. Но вы думаете, какие причины почему это происходит? – Khan9797

+0

Я решил проблему, изменив sprintf (copyPath, «% s //% s», path, nextFile-> d_name); в sprintf (copyPath, "% s \\% s", path, nextFile-> d_name); Когда я отлаживался, у меня возникла ошибка сегментации, почему я так ошибался, что я так понимаю, почему я не получил эту ошибку в начале? – Khan9797

ответ

1

Есть по крайней мере 3 проблемы в вашем коде, которые могут объяснить крах:

  • буферов, используемые для хранения полных имен путей платить слишком короткие, и вы используете небезопасную sprintf построить их, потенциально вызывая переполнение буфера.
  • Вы никогда не закрываете ручки каталога subFolder, которые вы открываете в рекурсивной функции showingFiles, потенциально заканчивая системными ручками.
  • вы закрываете ручку каталога currentFolder в функции showingFiles(), но она также закрыта в функции main(). Это вызывает неопределенное поведение. Как правило, всегда закрывайте дескриптор функции, которая открывала ее и только там.

Менее важные, но вопросы:

  • Чтобы назвать showingFiles функцию, которая выполняет рекурсивный удаление полного дерева каталогов немного вводит в заблуждение.

  • разделяющий каталог и пути с двойными косыми чертами // бесполезен и не переносится. Возможно, вы думали о \\ и преобразовали этот разделитель разделов Windows в // для портативности Unix, но имейте в виду, что одиночные косые черты :, поддерживаемые обработчиками файловой системы Windows, всегда должны использовать / в качестве разделителя каталогов для программ предназначенный как для Unix, так и для Windows.

Вот модифицированная версия:

#include <dirent.h> 
#include <stdio.h> 
#include <string.h> 

void deleteTree(DIR *, const char *); 

int main(void) { 
    char path[350] = "."; 
    DIR *folder = opendir(path); 

    if (folder != NULL) { 
     deleteTree(folder, path); 
     closedir(folder); 
    } 
    printf("\n\nEnter a key to close this program "); 
    getch(); 
    return 0; 
} 

void deleteTree(DIR *currentFolder, const char *path) { 
    char copyPath[1024]; 
    struct dirent *nextFile; 
    DIR *subFolder; 

    while ((nextFile = readdir(currentFolder)) != NULL) { 
     snprintf(copyPath, sizeof(copyPath), "%s/%s", path, nextFile->d_name); 
     printf("%s\n", nextFile->d_name); 
     if (strcmp(nextFile->d_name,"..") 
     && strcmp(nextFile->d_name,".") 
     && (subFolder = opendir(copyPath)) != NULL) { 
      deletingFiles(subFolder, copyPath); 
      closedir(subFolder); 
     } 
    } 
} 
+0

если использовать закрытый (subFolder), мы также бесплатно (nextFile)? , и будет ли это иметь значение, если мы поставим закрытие вне цикла, как последний оператор функции? – Khan9797

+0

'nextFile' не должно быть освобождено. 'closedir (subFolder);' должен вызываться только в том случае, если 'opendir()' преуспел, поэтому внутри блока 'if'. Если вы не вызываете 'closedir()' там, следующий 'opendir()' будет перезаписывать переменную 'subFolder', вызывая утечку ресурсов. – chqrlie