Правильный способ построения пути с использованием cstrings в C ++ - PullRequest
0 голосов
/ 09 октября 2010

Мне нужно создать путь к файлу. У меня есть следующий метод класса:

void Directory::scanDirectory(char *directory) {
    DIR *dirp;
    struct dirent *entry;
    char path[1];

    if(dirp = opendir(directory)) {
        while(entry = readdir(dirp)) {
            if (entry->d_name[0] != '.') {
                strcpy(path, directory);
                strcat(path, "/");
                strcat(path, entry->d_name);
                if (entry->d_type == 8) {
                    // Files
                } else if (entry->d_type == 4) {
                    //scanDirectory(path);
                }
                printf("Name: %s, Type: %d\n", entry->d_name, entry->d_type);
            }
        }
        closedir(dirp);
    }
}

Мне нужно создать путь к файлам путем объединения каталога и entry->d_name. Когда я пытаюсь запустить этот код, он segfaults. Из того, что я могу сказать, это segfaulting в точке, где я строю путь. Есть ли лучший способ сделать это?

Ответы [ 5 ]

3 голосов
/ 09 октября 2010

Вы выделяете только один байт для пути (char path[1]).Вам нужно выделить достаточно места, чтобы фактически сохранить весь путь, который вы создаете.Учитывая тег C ++, очевидной возможностью будет использование std::string, а после того, как вы соберете все части вместе в полный путь, используйте функцию-член c_str(), чтобы получить доступ к содержимому в стиле Cстрока.

2 голосов
/ 09 октября 2010

Почему бы не использовать Boost.Filesystem ?

1 голос
/ 09 октября 2010

Будьте осторожны, используя strcpy.Он не выполняет проверку границ, поэтому, хотя path - это всего лишь char[1], он попытается скопировать в него все directory.Вероятно, это ваша ошибка сегмента.

У вас есть много вариантов, как создать строку.Вот длинная статья SO об эффективности конкатенации строк в C ++:

Эффективная конкатенация строк в C ++

Если вы используете C ++, есть ли причина, по которой вы не можете простоиспользовать встроенную библиотеку string с оператором +?Например:

string path;
//...
path += directory;
path += "/";
path += entry->d_name;
//etc.

Использование класса string может быть немного менее эффективным, но это даст дополнительное преимущество, помогая вам избежать проблем переполнения буфера и исключений памяти, таких как ошибка сегментации, которую вы получаете (яЯ не говорю, что string избежит всего этого, но это облегчит вашу жизнь).

Также был другой предыдущий пост SO о том, как создать строку каталога в C ++:

c ++ как создать каталог из пути

1 голос
/ 09 октября 2010

Изменить char path[1]; на:

char path[512]; //or whatever value you like.

В вашем коде путь выделен только для 1 символа и \0. Очевидно, вам нужен больший, и, насколько я знаю, в unix имя каталога может быть длиной до 255 символов, поэтому, по моему мнению, достаточно 512.

1 голос
/ 09 октября 2010

В буфере path должно быть достаточно места для хранения всего пути. Прямо сейчас в нем есть место только для одного персонажа. Попробуйте сделать это больше. strcat не выделяет само пространство. Вы должны вручную управлять этой памятью.

Что касается лучшего способа, вы можете использовать строку . Вам не нужно беспокоиться о памяти, и вы можете объединить с оператором +.

...