C语言 将文件与路径连接以获取 C 中的完整路径

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2153715/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 04:17:46  来源:igfitidea点击:

Concatenating file with path to get full path in C

clinuxfileunix

提问by Derek

Using C, I'm trying to concatenate the filenames in a directory with their paths so that I can call stat() for each, but when I try to do using strcat inside the loop it concatenates the previous filename with the next. It's modifying argv[1] during the loop, but I haven't worked with C in a long time, so I'm very confused...

使用 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;
}

回答by Alok Singhal

You shouldn't modify argv[i]. Even if you do, you only have one argv[1], so doing strcat()on it is going to keep appending to whatever you had in it earlier.

你不应该修改argv[i]. 即使你这样做了,你也只有一个argv[1],所以strcat()对它进行操作将继续附加到你之前拥有的任何内容。

You have another subtle bug. A directory name and file names in it should be separated by the path separator, /on most systems. You don't add that in your code.

你有另一个微妙的错误。/在大多数系统上,目录名和其中的文件名应该用路径分隔符分隔。您不会在代码中添加它。

To fix this, outside of your while loop:

要解决此问题,请在 while 循环之外:

size_t arglen = strlen(argv[1]);

You should do this in your whileloop:

您应该在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);

回答by user151019

Where is the memory that you are copying to? path is allocated on the stack to contain the arguments you need yo allocate the memory yourself e.g.

您要复制到的内存在哪里?路径在堆栈上分配以包含您需要自己分配内存的参数,例如

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

In production code se strncat etc to stop overflows

在生产代码 se strncat 等中停止溢出

回答by user151019

You must not try to increase the size of argv[1] by strcat'ing to it (and changing it at all is a bad idea) - that will cause undefined behaviour. Instead, copy argv[1] into a suitable sized buffer and work with that:

你不能试图通过对它进行 strcat'ing 来增加 argv[1] 的大小(并且根本改变它是一个坏主意) - 这将导致未定义的行为。相反,将 argv[1] 复制到合适大小的缓冲区中并使用它:

char path[1000];   // or some suitable size;
strcpy( path, argv[1] );

回答by Frerich Raabe

The problem is that the line

问题是这条线

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

keeps appending the name of the current file to path. Try creating a new string for the full path each time, like

不断将当前文件的名称附加到path. 每次尝试为完整路径创建一个新字符串,例如

char* fullpath = calloc(strlen(path) + strlen(ep->d_name) + 1);
strcat(fullpath, path);
strcat(fullpath, ep->d_name);
/* .. */
free(fullpath);