Ошибка сегментации для моего символа ** и поврежденных строк - PullRequest
1 голос
/ 10 апреля 2020

Я хочу написать программу, которая принимает строковый ввод как расширение и должна сохранять все имена файлов в моем символе **.

В данный момент ввод жестко закодирован в вызове функции в строке 50

Но я получаю ошибку сегмента и, если я хочу напечатать i <2 в строке 54, вывод будет довольно поврежден. </p>

Есть предложения?

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


void getFiles (char* extension, char** fileNames, int* len)
{
    *len = 0;
    //*(fileNames + 1) = "Test 2";

    DIR *d;
    struct dirent *dir;
    d = opendir(".");
    if (d)
    {
        while((dir = readdir(d)) != NULL)
        {
            if (!(strcmp (extension, strrchr (dir->d_name, '.') + 1)))

            {
                (*len) ++;
                printf("%d\n", *len);
                char** tmp = realloc (fileNames, sizeof (char*) * ((*len)));
                if (tmp == NULL)
                {
                    printf("error\n");
                    exit (1);
                }
                fileNames = tmp;
                *(fileNames + (*len) - 1) = (char*) dir->d_name;
                printf("%s\n", *(fileNames + (*len) - 1));
            }
        }
        closedir(d);
    }
    *(fileNames + 1) = "test";
}


int main()
{
    char** fileNamePointer;
    int* len;
    len = (int *) malloc (sizeof (int));
    *len = 0;
    fileNamePointer = (char**) malloc (sizeof(char*));


    getFiles ("csv", fileNamePointer, len);

    int i;
    printf("len: %d\n", *len);
    for (i = 0; i < (*len); i++)
    {
        printf("%s\n", *(fileNamePointer + i));

    }

}

Выход если я печатаю, я <2 в строке 56 </p>

1

test.csv

2

test2.csv

3

test3.csv

4

test4.csv

len: 4

8▒0▒

8▒ 0▒

1 Ответ

0 голосов
/ 10 апреля 2020

Следующая программа использует структуру files_s для передачи указателей на массив строк и длины вокруг.

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

struct files_s {
    char **names;
    size_t len; // use size_t type to represent "count" of elements
};

// helper function to free all the names
void files_free(struct files_s *t) {
    for (size_t i = 0; i < t->len; ++i) {
        free(t->names[i]);
    }
    free(t->names);
    t->names = NULL;
    t->len = 0;
}

// extension is a constant
// files is passed by a pointer
void getFiles(const char *extension, struct files_s *files)
{
    // initialization
    files->len = 0;
    files->names = NULL; // realloc can work with NULL as initial value

    DIR *d = opendir(".");
    // error handlign
    if (d == NULL) {
        // the unix style goto error handling
        // https://www.kernel.org/doc/html/v4.10/process/coding-style.html#centralized-exiting-of-functions
        goto ERROR;
    }

    // declare variables near use
    struct dirent *dir;
    while ((dir = readdir(d)) != NULL) {
        // error handling
        const char * const dot = strrchr(dir->d_name, '.');
        if (dot == NULL) {
            continue;
        }

        if (strcmp(extension, dot + 1) == 0) {

            // use sizeof(*variable) in *alloc calls
            void *tmp = realloc(files->names, sizeof(files->names[0]) * (files->len + 1));
            if (tmp == NULL) {
                goto ERROR;
            }
            files->names = tmp;

            // duplicate the memory for the entry name
            char *newstr = strdup(dir->d_name);
            if (newstr == NULL) {
                goto ERROR;
            }

            // add new entry to the array
            files->names[files->len] = newstr;
            files->len++;
        }
    }
    closedir(d);
    return; // SUCCESS

    ERROR:
    // handle error
    // remember to free all elements
    files_free(files);
    abort();
}

int main() {
    struct files_s files;
    getFiles("csv", &files);
    // the size_t type is printed with %zu
    printf("len: %zu\n", files.len);
    for (size_t i = 0; i < files.len; i++) {
        printf("%s\n", files.names[i]);
    }
    // remember to pick out the trash
    files_free(&files);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...