Объединение файла с путем, чтобы получить полный путь в C - PullRequest
3 голосов
/ 28 января 2010

Используя C, я пытаюсь объединить имена файлов в каталоге с их путями, чтобы я мог вызывать stat () для каждого, но когда я пытаюсь использовать strcat внутри цикла, он объединяет предыдущее имя файла со следующим , Он изменяет argv [1] во время цикла, но я долгое время не работал с C, поэтому я очень запутался ...

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

int main(int argc, char *argv[]) {
 struct stat buff;

 int status;

 if (argc > 1) {
  status = stat(argv[1], &buff);
  if (status != -1) {
   if (S_ISDIR(buff.st_mode)) { 
     DIR *dp = opendir(argv[1]);
     struct dirent *ep;
     char* path = argv[1];
     printf("Path = %s\n", path);

     if (dp != NULL) {
       while (ep = readdir(dp)) {
       char* fullpath = strcat(path, ep->d_name);
       printf("Full Path = %s\n", fullpath);
     }
     (void) closedir(dp);
   } else {
      perror("Couldn't open the directory");
   }
 }

  } else {
   perror(argv[1]);
   exit(1);
  }
 } else {
   perror(argv[0]]);
                exit(1);
 }

 return 0;
}

Ответы [ 4 ]

10 голосов
/ 28 января 2010

Вы не должны изменять argv[i]. Даже если у вас есть, у вас есть только один argv[1], так что выполнение strcat() будет продолжать добавлять к тому, что было в нем ранее.

У вас есть еще одна тонкая ошибка. Имя каталога и имена файлов в нем должны быть разделены разделителем пути, / в большинстве систем. Вы не добавляете это в свой код.

Чтобы это исправить, вне вашего цикла while:

size_t arglen = strlen(argv[1]);

Вы должны сделать это в цикле while:

/* + 2 because of the '/' and the terminating 0 */
char *fullpath = malloc(arglen + strlen(ep->d_name) + 2);
if (fullpath == NULL) { /* deal with error and exit */ }
sprintf(fullpath, "%s/%s", path, ep->d_name);
/* use fullpath */
free(fullpath);
1 голос
/ 28 января 2010

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

char path[1024] ;   // or some other number
strcpy( path, argv[1] );
// then separator
strcat( path, "/" ) ; // or "\\" in Windows
strcat( path, ep->d_name);

В рабочем коде se strncat и т. Д. Для остановки переполнения

0 голосов
/ 28 января 2010

Проблема в том, что линия

char* fullpath = strcat(path, ep->d_name);

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

char* fullpath = calloc(strlen(path) + strlen(ep->d_name) + 1);
strcat(fullpath, path);
strcat(fullpath, ep->d_name);
/* .. */
free(fullpath);
0 голосов
/ 28 января 2010

Вы не должны пытаться увеличить размер argv [1], указав на него strcat'ing (и вообще изменить его - плохая идея) - это приведет к неопределенному поведению. Вместо этого скопируйте argv [1] в буфер подходящего размера и работайте с этим:

char path[1000];   // or some suitable size;
strcpy( path, argv[1] );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...