如何从命令行正确传递文件路径?
How to properly pass file path with from the command line?
我有一个关于将某些文件从一个目录移动到另一个目录的项目。除了输出有点奇怪外,我都完成了。我需要在 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
而且第一个参数似乎也崩溃了...
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);
}
这个:
char *dest = argv[3]
使 dest
指向与 argv[3]
相同的字符串。也就是说,您复制的是指针,而不是它指向的数据。当您随后通过 dest
修改该数据时,您正在修改参数本身。这是允许的,但形式不佳。
更大的问题是你实际用它做了什么。这个:
strcat(dest, "/");
strcat(dest, files[i].justname);
尝试将数据附加到参数字符串的末尾,但假设(在实践中这可能是不正确的)在指向的数组中有任何空闲的 space 是不安全的存储额外的字符。如果确实没有足够的 space 那么你会产生未定义的行为。
根据您展示的代码和描述的行为,我推测您没有展示的内容可能包括对指向 [=16= 的另一个参数指针的类似赋值].这样的分配本质上并不是错误的,但它很容易使 UB 的表现比现在更加混乱。
无论如何,如果你想形成程序参数的串联,那么你需要为结果保留单独的 space。您可以使用足够大的自动数组或足够大的动态分配 space 来做到这一点。后者可能看起来像这样:
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()
更清晰。
我有一个关于将某些文件从一个目录移动到另一个目录的项目。除了输出有点奇怪外,我都完成了。我需要在 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
而且第一个参数似乎也崩溃了...
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);
}
这个:
char *dest = argv[3]
使 dest
指向与 argv[3]
相同的字符串。也就是说,您复制的是指针,而不是它指向的数据。当您随后通过 dest
修改该数据时,您正在修改参数本身。这是允许的,但形式不佳。
更大的问题是你实际用它做了什么。这个:
strcat(dest, "/");
strcat(dest, files[i].justname);
尝试将数据附加到参数字符串的末尾,但假设(在实践中这可能是不正确的)在指向的数组中有任何空闲的 space 是不安全的存储额外的字符。如果确实没有足够的 space 那么你会产生未定义的行为。
根据您展示的代码和描述的行为,我推测您没有展示的内容可能包括对指向 [=16= 的另一个参数指针的类似赋值].这样的分配本质上并不是错误的,但它很容易使 UB 的表现比现在更加混乱。
无论如何,如果你想形成程序参数的串联,那么你需要为结果保留单独的 space。您可以使用足够大的自动数组或足够大的动态分配 space 来做到这一点。后者可能看起来像这样:
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()
更清晰。