Как скопировать символ в вектор *

Я использую dirent для чтения имен файлов из определенной папки, и я хочу сохранить имена в символьном * векторе. Кажется, что он копирует некоторые странные символы вместо того, чтобы копировать имена файлов. Это то, что я пробовал до сих пор:

std::vector<char*> filenames;

int filenamesAndNumberOfFiles(char *dir)
{
struct dirent *dp;
DIR *fd;
int count = 0;

if ((fd = opendir(dir)) == NULL)
{
fprintf(stderr, "listdir: can't open %s\n", dir);
return 0;
}
while ((dp = readdir(fd)) != NULL)
{
if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
continue;    /* skip self and parent */
printf("Filename: %s\n", dp->d_name);
filenames.push_back(dp->d_name);
count++;
}
closedir(fd);
return count;
}

Может кто-нибудь сказать мне, почему он не копирует имена файлов и как я могу сделать, чтобы скопировать их?

Редактировать:
d_name — это переменная типа char, объявленная как:

char d_name[PATH_MAX];

и похоже, что в моей программе PATH_MAX равен 260.

PS: это мой первый раз, когда я использую dirent, поэтому я не очень знаком с ним.

2

Решение

Как сказал user2079303, второй вызов readdir перезапишет результаты, возвращенные первым вызовом (ссылка на сайт).

Но я бы порекомендовал вам использовать строку для этого в C ++:

std::vector<std::string> filenames;

int filenamesAndNumberOfFiles(char *dir)
{
struct dirent *dp;
DIR *fd;
int count = 0;

if ((fd = opendir(dir)) == NULL)
{
fprintf(stderr, "listdir: can't open %s\n", dir);
return 0;
}
while ((dp = readdir(fd)) != NULL)
{
if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
continue;    /* skip self and parent */
printf("Filename: %s\n", dp->d_name);
filenames.push_back( std::string(dp->d_name) );
count++;
}
closedir(fd);
return count;
}

Вы всегда можете использовать c_str() если вам нужен char* позже.

1

Другие решения

замещать std::vector<char*> с std::vector<std::string>, И добавить #include <string>, Это должно решить проблему.

Похоже, вы еще не поняли концепцию указателей и массивов в C / C ++, и я не уверен, объясняю ли это, что вписывается в рамки SO-ответа. Но этот ответ может быть полезен: C ++: копирует ли содержимое char указатель на преобразование std :: string?

Короче говоря, проблема с вашим кодом заключается в том, что вместо копирования памяти, в которой хранится строка (сами символы, char[PATH_MAX]), вы только копировали указатель на эту память (char*). И указанный ранее блок памяти был повторно использован или даже удален, в результате чего сохраненный указатель стал недействительным.

6

Вам нужно хранить копии строки. использование vector<string>, Когда ты push_back(dp->d_name) вы храните висячий указатель, потому что dp выходит из области видимости после завершения функции.

3

Это потому, что вы нажимаете указатель, dp->d_name на вектор, однако строка, на которую указывает указатель, исчезает при вызове следующего readdir() вызов.

Вместо этого вы должны сделать копию этой строки и вставить ее в вектор:

filenames.push_back(strdup(dp->d_name));

Теперь вы должны не забыть освободить () эту строку, которая копируется в вектор, когда вы закончите с filenames вектор

Однако, пожалуйста, не делайте этого вообще. Просто используйте:

std::vector<std::string> filenames;

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

2
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector