了解C中的scanf

Jus*_*ung 2 c scanf

所以我对编程很新,我在3天前开始使用C语言.我正在创建这个简短的程序来测试自己.这只是一个非常基本的C程序,要求你的名字和姓氏.这是代码:

#include <stdio.h>

int main() 
{

    char first[20];

    char last[20];

    printf("Please enter your first name:");
    scanf("%s",&first);
    printf("\nand Please enter your last name:");
    scanf("%s",&last);
    printf("Greetings fellow %s %s!\n",first,last);
    return(0);
}
Run Code Online (Sandbox Code Playgroud)

但是当我去编译时,我每次都会得到这个错误:

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

我知道我可以使用,gets()但显然它很糟糕,我不应该使用它.这段代码有什么问题?我不明白问题是什么.

小智 7

我知道我可以使用,gets()但显然它很糟糕,我不应该使用它.

确切地说,确切地说 - 它容易出现缓冲区溢出错误.并且scanf()同样是邪恶的(部分是出于同样的原因 - 指定缓冲区长度并不容易,而且无论如何,它都比必要的更复杂,很难做到正确,而且对于简单的原始I/O来说它是非常昂贵的),不要也不要用它.使用fgets()获取用户输入,它通过让在脚被枪击节省您传递给它的缓冲区的长度被写入到:

char buf[0x40];
fgets(buf, sizeof(buf), stdin);
Run Code Online (Sandbox Code Playgroud)

既然你知道"如何",我会向你解释"为什么".

传递给函数时,数组被称为衰减为指针.如果将a传递char []给函数,它将看到char *它指向数组的第一个元素.这就是为什么你不必&为(char)数组(概念上是C中的字符串)显式使用"addressof"()运算符的原因.

如果使用它,则不会获得指向数组的第一个元素的指针,而是指向数组本身的指针,而这不是您想要的.

(一般来说,它可以工作,因为它显然对你有用,但理论上它会调用未定义的行为,因为传入的表达式的实际类型和%s转换说明符所期望的类型不匹配.)

本文档是关于数组和指针的一个很好的读物,请务必阅读并理解它.