如何正确使用命令行传递文件的路径? [关闭](How to properly pass file

2019-10-30 03:53发布

关闭。 这个问题是题外话。 它目前不接受的答案。 了解详情 。


我有一个关于从一个目录移动某些文件到另一个项目。 我已经全部完成,但其输出是那样的陌生。 我需要提供argsv阵列中的目标路径,但是当我尝试执行我的代码,它编译和作品,但显示包含在一个多路走错了路! 下面是相关的部分,如果你需要更多的代码,我会加! 先感谢您!

int main(int argc, char **argv)
{

int size = NFILES;
int index = -1;
file * files = malloc(size * sizeof(file));

listFilesRecursively(argv[1], &files, &size, &index);

if (index != -1) {
      int N = atoi(argv[2]);

if(N==1) qsort(files, index + 1, sizeof(file), compPathname);
else if(N==2) qsort(files, index + 1, sizeof(file), compPathsize);

for (int i = 0; i <= index; ++i) {
        char *dest = argv[3];
                strcat(dest, "/");
                strcat(dest, files[i].justname);
  printf("%s : %s : %ld\n", files[i].name, dest , (long)   files[i].file_info.st_size);
//  if(rename(files[i].name, dest)==0) printf("Success!\n"); else     printf("Failed!/n");
}

因此,这是主要的。 所需的输出是这样的(我有很多的文件):

./copyto.c : /home/nik/copyto.c : 676
Success!
./mvfilrd.c : /home/nik/mvfilrd.c : 957
Success!
./sortall.c : /home/nik/sortall.c : 992
Success!

等等......而是我得到

./newdir/newfile.txt : /home/nik/Music/newfile.txt : 0
Success!
./newdir/3.exe : /home/nik/Music/newfile.txt/3.exe : 0
Failed!/n./newdir/compil : /home/nik/Music/newfile.txt/3.exe/test :     0
Failed!/n./newdir/2.c : /home/nik/Music/newfile.txt/3.exe/test/exe :         0 

然后更是垃圾

Failed!/n./newf.exe : /home/nik/Music/newfile.txt/3.exe/test/exe    /1//Q�/~�dZ /�l�G^ /
                                                                                    ��`(/4�a^d /a.txt/range/1.txt/1.exe/print.exe/filrd.exeC/2.exre/filrd.exe/2.exe/fi.txt/fil.txt/dest.txt/sorcopy.c/filew.exe/.filer.c.swp    /progfilrd.exe/compile/myfile/.m

和第一个参数似乎已经崩溃,以及...

Answer 1:

char *dest = argv[3]; 
strcat(dest, "/"); 
strcat(dest, files[i].justname); 

哎哟你修改你没有自己的字符串,不这样做,你可能写出来的字符串,在工作副本

更换

for (int i = 0; i <= index; ++i) {
    char *dest = argv[3];
    strcat(dest, "/");
    strcat(dest, files[i].justname);
    printf("%s : %s : %ld\n", files[i].name, dest , (long)   files[i].file_info.st_size);
    if(rename(files[i].name, dest)==0) 
       printf("Success!\n");
    else
       printf("Failed!/n");
}

通过

for (int i = 0; i <= index; ++i) {
    size_t sz = strlen(argv[3]);
    char *dest = malloc(sz + strlen(files[i].justname) + 2);

    strcpy(dest, argv[3]);
    dest[sz] = '/';
    strcpy(dest + sz + 1, files[i].justname);

    printf("%s : %s : %ld\n", files[i].name, dest , (long)   files[i].file_info.st_size);
    if(rename(files[i].name, dest)==0)
      printf("Success!\n");
    else
      printf("Failed!/n");

    free(dest);
}


Answer 2:

这个:

    char *dest = argv[3]

使得dest点到相同的字符串argv[3]一样。 也就是说,你复制的指针,而不是它所指向的数据。 当您随后修改通过数据dest ,要修改参数本身。 这是允许的,但拙劣的形式。

更大的问题是什么,你居然用它做什么。 这个:

  strcat(dest, "/"); 
  strcat(dest, files[i].justname);

试图将数据追加到参数字符串的结束,但它是不安全的假设(和它在实践中可能不正确),有任何自由空间指向的阵列来存储多余的字符。 如果确实没有足够的空间,那么你产生不确定的行为。

基于你做节目的代码和你所描述的行为,我猜测,你没有显示可能包括其他参数指针的类似的分配files[i].justname 。 这样的分配是不是天生错的,但它可以很容易使UB的表现更加混乱比它已经是。

在任何情况下,如果要形成的程序参数并置,那么你需要保留独立的空间的结果。 你可以做一个足够大的自动阵列,或具有足够大的动态分配的空间。 后者可能是这样的:

    size_t path_chars = strlen(argv[3]) + strlen(files[i].justname) + 2;
    char *path = malloc(path_chars);

    if (path) {
        sprintf(path, "%s/%s", argv[3], files[i].justname);
    } // else handle memory allocation failure

您可以使用strcpy()strcat()而不是如果你喜欢,但在这种特殊情况下,我认为sprintf()是更清晰和更清洁。



文章来源: How to properly pass file path with from the command line? [closed]