我是C的新手,我所知道的是错误与oldname
和newname
未初始化相关
#include <stdio.h>
int main (int argc, char const *argv[])
{
int result;
int lengthOne;
int lengthTwo;
lengthOne = sizeof(argv[0]);
lengthTwo= sizeof(argv[1]);
char oldname[lengthOne] = argv[0];
char newname[lengthOne] = argv[1];
result = rename(oldname, newname);
if (result == 0) {
puts "File renamed";
} else {
perror "ERROR: Could not rename file";
}
return 0;
}
app.c: In function ‘main’:
app.c:11: error: variable-sized object may not be initialized
app.c:12: error: variable-sized object may not be initialized
app.c:17: error: expected ‘;’ before string constant
app.c:19: error: expected ‘;’ before string constant
答案 0 :(得分:9)
lengthOne = sizeof(argv[0]);
lengthTwo= sizeof(argv[1]);
这会为您提供char*
,不字符串长度的大小。您的意思是strlen
,而不是sizeof
。
char oldname[lengthOne] = argv[0];
char newname[lengthOne] = argv[1];
您不能像这样分配数组。你可以strcpy
他们,但这里没必要,因为你可以使用指针。
const char* oldname = argv[0];
const char* newname = argv[1]; // But verify that argc >= 2 first!
编辑:另外,不要忘记argv[0]
是程序本身的名称,argv[1]
是第一个参数。如果您打算编写类似mv
的程序而不是重命名的程序,则需要argv[1]
和argv[2]
。
答案 1 :(得分:5)
您似乎无法理解C中的指针。这是一个非常核心的概念,您需要了解才能使用该语言。
我将从他们的教程开始。一个guick google将此作为第一个结果:http://pw1.netcom.com/~tjensen/ptr/pointers.htm
答案 2 :(得分:1)
首先,char x[length] = /* something */;
仅适用于字符串文字(例如"string"
或{'s', 't', 'r', 'i', 'n', 'g', '\0'}
,如果你想要受虐待)。
其次,要调用函数,请使用括号。 puts("Text");
和printf("Text\n");
。它们不像某些语言那样是可选的。
第三,作为函数参数(即使它是main()
的参数),数组类型衰减为指针。所以你的函数签名实际上是int main(int argc, char **argv)
(我更喜欢用这种方式编写,就个人而言,但没有区别)。你不能将sizeof
一个已经衰变的数组带到一个指针,因为它不再是一个数组,并且没有关于它的大小的相关信息。要获得尺寸,请使用strlen()
。
第四,使用size_t
来存储尺寸。使用int
存储大小是错误的 - 不能保证int
足够大以容纳大小,并且您不能拥有任何类型的-5大小的对象。 size_t
是标准中包含的无符号整数类型,用于此目的。
最后,如果您需要一个大小取决于运行时条件的对象,则不能使用数组。您必须使用指针,并使用malloc
创建一个正确大小的内存块,然后在完成后使用free
销毁它。编辑:或者只是将argv[0]
指定给指针。标准中保证argv
可写,因此您可以编辑它(只是尽量避免附加任何内容)。
答案 3 :(得分:1)
sizeof是一个编译时检查...任何argv元素的sizeof都是指向char的指针中的字节数。它与指针可以解决的文本的运行时长度无关:strlen()
返回该值。但是,C不允许您创建动态(即运行时)大小的数组。即便如此,您也无法使用=
将字符串复制到另一个字符串中......它需要调用strcpy(dest, src)
。为了使它工作,显然最简单的事情是:
result = rename(argv[0], argv[1])
但是,我很感激您正在尝试学习如何将值复制到您自己的缓冲区中。为此,您需要动态创建足够大的缓冲区(内存分配或malloc
),对其进行字符串复制,然后使用它free
。 strdup()
函数满足了其中一些要求:
const char* p_old_name = strdup(argv[0]);
const char* p_new_name = strdup(argv[1]);
rename(p_old_name, p_new_name);
free(p_old_name);
free(p_new_name);
或者,你可以静态地指定两个字符串的最大大小(如果你弄错了会很危险 - strncpy()可以提供更多的安全性但是错误可能仍会阻止你的程序使用一些长而有效的路径) :
#include <linux/limit.h> // or wherever you can find PATH_MAX or similar
...
char old_name[PATH_MAX];
char new_name[PATH_MAX];
strcpy(old_name, argv[0]);
strcpy(new_name, argv[1]);
rename(old_name, new_name);
注意:由于argv[0]
是程序名,因此该程序将其自己的可执行文件名更改为第二个参数。如果您希望它更改其他文件的名称,则应使用argv[0]
和argv[1]
。
答案 4 :(得分:0)
sizeof()返回类型的大小 - 即指针的大小(可能是32位)或char(8位)
要获得字符串的长度,您需要strlen()
此外,在ansi C中,您无法创建具有大小变量的数组。您可以使用新的C标准,或者现在可以使用malloc()创建数组
答案 5 :(得分:0)
argv
属于char*[]
类型,即指向char的指针数组。因此,任何第一级元素都只是char*
,因此,sizeof(argv [i])将始终返回本机指针大小。您需要使用strlen或一些等效函数来获取字符串的长度。