2010-03-13 64 views
3

当我编译scanf("%s", &var);,GCC发送回一个警告:使用在scanf符号()

warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char (*)[20]’ 

然而当我编译scanf("%s", var);,没有施加警告。代码工作和我正在阅读的书都特别说明了使用&符号,但即使它并不在某些示例中。

我的问题是,即使书中没有指定,我是否应该继续使用&符号?

+3

直到你知道什么是指针,如果它是'%s',不要使用'&',否则总是使用它。 (Duplicate?http://stackoverflow.com/questions/2062648/c-scanf-question) – kennytm 2010-03-13 19:38:25

回答

4

从你发布的内容var是一个字符数组。在这种情况下,您不需要&符号,只需要名称var将根据需要计算为(char *)。

详细说明:

scanf的需要一个指向将存储输入变量。在字符串的情况下,需要一个指向内存中字符数组的大小的指针,以存储所读取的任何字符串。当您声明类似char var[100]的东西时,将使用var [0]指向100 char s的空间第一个字符和var [99]指的是第100个字符。数组名称本身的计算结果与&var[0]的计算结果完全相同,它是指向序列第一个字符的指针,正是scanf所需的。所以你需要做的只是scanf("%s", var);,但是请注意scanf不会对输入字符串实施大小限制,所以如果用户输入一个长度为101的字符串,你将会有一个缓冲区溢出,这会导致错误或者甚至更糟的是安全性问题。更好的选择通常是fgets,它允许输入字符串的大小限制。

+1

可以使用scanf指定长度。 'scanf(“%10s”,var);' – Leandro 2010-05-31 02:47:00

1

我邀请其他答复者对这里的指针和参考文献进行一个很好的总结。我不认为我能做到这一点,而不是在这里或那里犯一些错误,而且我也不打算处理随之而来的书呆子狂怒。

因此,我只是指您一个好resource了解指针和引用,这是问题的核心。 http://www.cplusplus.com/doc/tutorial/pointers/

+0

+1对于典型的SO书呆子愤怒...有时似乎有一个比赛在某个地方看到谁可以发布最多的“但是!但是!未定义的行为OMG”在一天的评论。 – SoapBox 2010-05-31 02:53:11

0

当你使用像这样的数组:

char name[20]; 

,你必须考虑到由20个字符组成的存储区域与它关联。要获取该内存区域的开始地址,您必须使用数组的名称,而要获取该数组的单个字符的地址,则必须使用如下的sintax:& name [i]。
您正在使用scanf读取一个字符串,该字符串是C中的一个char数组。scanf需要与要读取的变量类型关联的内存区的地址。在这种情况下,您正在读取数组,因此您只需使用该名称。 如果您想读取单个变量而不是数组,则必须使用&符号。例如:

char myChar; 
scanf("%c", &myChar); 

我希望这会有所帮助。

1

scanf("%s", &var);中删除&,因此它是scanf("%s", var);