2010-10-09 1 views
0

Мне нужно создать путь к файлу. У меня есть следующий метод класса:Правильный способ создания пути с использованием cstrings в C++

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 в точке, где я строю путь. Есть ли лучший способ сделать это?

ответ

1

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

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

3

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

1

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

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

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

1

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

У вас есть много вариантов с точки зрения построения строки. Вот длинный пост на SO эффективности конкатенации C++:

Efficient string concatenation in C++

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

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

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

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

c++ how to create a directory from a path