使用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;
}
答案 0 :(得分:10)
您不应修改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 :(得分:1)
您要复制到的内存在哪里? path被分配在堆栈上以包含你需要的参数你自己分配内存,例如。
char path[1024] ; // or some other number
strcpy( path, argv[1] );
// then separator
strcat( path, "/" ) ; // or "\\" in Windows
strcat( path, ep->d_name);
在生产代码中使用strncat等来阻止溢出
答案 2 :(得分:0)
你不能试图通过strcat来增加argv [1]的大小(并且根本改变它是一个坏主意) - 这将导致未定义的行为。相反,将argv [1]复制到合适大小的缓冲区中并使用:
char path[1000]; // or some suitable size;
strcpy( path, argv[1] );
答案 3 :(得分:-1)
问题在于行
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);