scanf的问题
scanf与scanf_s的区别
在VS中往往会出现初学者都会手忙脚乱的事情,例如长期使用VC++6.0的学习者都会出现这个问题,在VC中不出错的代码往往会在VS中出现大量的错误,其实并不都是自己的问题,而是Microsoft 弃用了某些 CRT C++和标准库函数和全局函数,因为提供了更安全的版本。 大多数不推荐使用的函数允许对缓冲区进行未检查的读取或写入访问。 它们可能会导致严重的安全问题。 编译器会发出对这些函数的弃用警告,并建议首选函数。
这可能就像是HTTP与HTTPS一样的关系,scanf与scanf_s的安全性的问题,自然是后者的安全性高于前者,所以才导致前者被弃用。我想以上的东西都是我们初学者应该去学习和了解的东西。
for (int i = 0; i < 3; ++i)
{
//gets(a[i]);
scanf_s("%s", a[i],30);
/*getchar();*/
}
正是因为scanf函数字符串有溢出的问题,所以才出现了scanf_s函数,而后者也正是多了限制字符串溢出的参数,scanf_s("%s", a[i],30);
,最后的编译结果才不会报错,所以在使用VS之前一定要有这样的预备知识,不然会很被动,一定要清楚有的函数已经不适用于现在的环境。
scanf和getchar
while(i < FAMAX && gets(movies[i].title)!=NULL &&movies[i].title[0] != '\n')
{
puts("请输入你对影片的评分:(0-10)");
scanf("%d",&movies[i++].rating);
//while (getchar()!='\n')
//continue;//scanf 函数会接受到空行,直接跳过输入字符环节
puts("请输入下一个影片的名字:");
}
当注释掉getchar的整个语句之后,第一次循环开始,输入影片名之后,利用scanf函数继续输入影片评分,缓冲区内存入(10\n),由scanf函数将10拿出f赋给movies[i++].rating,之后缓冲区就留下了“\n”,程序继续运行之后,到第二次循环开始,gets函数读取了缓冲区的“\n”,换行符不作为读取串的内容,读取的换行符被转换为‘\0’空字符,并由此来结束字符串。所以程序将不会存入你想要存入的影片名字。
缓冲区 | 输入 |
---|---|
待定 | 10 \n |
执行scanf函数之后
缓冲区 | 剩余 |
---|---|
\n |
执行gets函数之后
缓冲区 |
---|
而其中的getchar代码起到了一个清空缓冲区的作用
//while (getchar()!='\n')
//continue;
getchar函数在用户输入的字符被存放在键盘缓冲区中。直到用户按回车为止(回车字符也放在缓冲区中)。当用户键入回车之后,getchar才开始从缓冲区每次读入一个字符。
scanf函数在遇到空格和回车时都会停止读出,空格符则被转换成结束符“\0”,最后一个“\n”将被留在换冲区。