Как вы читаете, что находится в каталоге после его открытия? - PullRequest
1 голос
/ 22 февраля 2020

Почему я не могу прочитать то, что находится в каталоге, он продолжает давать мне ошибки сегментации?

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <dirent.h>

int count(char* loc)
{
        int num = 0;
        char c;
        FILE *file = fopen(loc, "r");
        while( (c = fgetc(file)) != EOF) {
                if(c == '\n')
                        num++;
        }
        int r = fclose(file);
        return num;
}

int main()
{
        int lines = 0;
        int files = 0;
        char* names[files];
        int i = 0;
        DIR* d = opendir("./visual");    //You can change this bit

        struct dirent *file;
        while((file = readdir(d)) != NULL){
                i++;
                names[i] = file->d_name;
                files++;
                printf("%s\n", names[i]);
        }
        closedir(d);
        printf("__________\n");
        for(int i = 0;i < files;i++){
                printf("i = %d\n", i);

                lines = lines + count(names[i]);
        }
        printf("you have written %d lines of code", lines);
}

1 Ответ

1 голос
/ 22 февраля 2020

Здесь вы определяете массив размером 0.

int files = 0;
char* names[files];

Здесь (в то время как i и files оба равны 0) вы получаете доступ к первому из этих нулевых элементов (обратите внимание на конфликт здесь?) в массиве.

names[i] = file->d_name;

Затем вы увеличиваете files.

files++;

Это, однако, не меняет размер массива, и даже если это будет слишком поздно .

Продолжая, я процитирую полезный комментарий WhozCraigs (с разрешения):

Даже исправляя это, вы все еще ожидаете пробуждения. names[i] = file->d_name будет хранить указатель на память, который не гарантируется и даже не может быть установлен на c в течение всего времени существования перечисления.
Он может / будет использоваться повторно при перечислении каждой записи файла. И даже если это не так, вся эта память гарантированно будет закрыта после запуска closedir.
Если вы хотите сохранить имена файлов, вам необходимо сделать их копии; не просто сохранить указатели.

Конец цитаты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...