paxdiablo..
171
人们(尤其是初学者)不应该使用scanf("%s")或者没有gets()任何其他没有缓冲区溢出保护的功能,除非您确定输入将始终是特定格式(甚至可能不是那样).
请记住,而不是scanf代表"扫描格式化",并且比用户输入的数据的格式少得多.如果您完全控制输入数据格式但通常不适合用户输入,这是理想的选择.
使用fgets()(具有缓冲区溢出保护)将输入转换为字符串并sscanf()进行评估.由于您只想要用户输入的内容而不进行解析,sscanf()因此无论如何您都不需要:
#include
#include
#include
/* Maximum name size + 1. */
#define MAX_NAME_SZ 256
int main(int argC, char *argV[]) {
/* Allocate memory and check if okay. */
char *name = malloc(MAX_NAME_SZ);
if (name == NULL) {
printf("No memory\n");
return 1;
}
/* Ask user for name. */
printf("What is your name? ");
/* Get the name, with size limit. */
fgets(name, MAX_NAME_SZ, stdin);
/* Remove trailing newline, if there. */
if ((strlen(name) > 0) && (name[strlen (name) - 1] == '\n'))
name[strlen (name) - 1] = '\0';
/* Say hello. */
printf("Hello %s. Nice to meet you.\n", name);
/* Free memory and exit. */
free (name);
return 0;
}
如果您只想从用户那里获得一条线,那就更容易了.它也更安全,因为您可以避免缓冲区溢出.scanf系列非常适用于将字符串转换为不同的东西(例如四个字符和一个int,例如"%c%c%c%c%d")但是,即使这样,你应该使用fgets和sscanf,而不是scanf,以避免缓冲区溢出的可能性. (7认同)
您可以将最大缓冲区大小设置为scanf格式,您只是不能在没有在运行时构建格式的情况下放置运行时计算的(没有相当于*for printf,*是scanf的有效修改器,具有另一种行为:抑制赋值). (4认同)