一、函数
1、输入函数
(1)scanf函数(从键盘上把数据输入到指定的变量之中)
头文件:stdio.h。
存不了空格符
(2)scanf_s函数
scanf()在读取时不检查边界,所以可能会造成内存访问越界,例如分配了5字节的空间但是读入了10字节。
scanf_s()函数进行检查输入边界,确保不会读取超过用户为缓存区分配的字符数,大大提高了安全性。
scanf_s() 需要提供两个参数:一个是用于存储输入的缓冲区,另一个是表示要读取的最大字符数。
例如:
#include <stdio.h>
int main()
{
char str[100];
printf("请输入一个字符串:");
scanf_s("%s", str, sizeof(str));
printf("您输入的字符串是:%s\n", str);
return 0;
}
在上面的示例中,%s是格式控制符,用于指定输入的数据类型为字符串。str表示将输入的字符串存储到字符数组str中。sizeof(str)表示str的最大字符数,以确保输入的字符串不会导致缓冲区溢出。
(3)gets函数和gets_s函数
函数声明
char * gets ( char * str );
在使用scanf函数时如果要输入一个含空格的字符串,那到空格的时候,scanf函数就停止从缓冲区读取字节,就会导致我们的目的没有达成
从标准输入流stdin中读取字符(包括空格,Tab),并将其作为C字符串存储到str中,直到到达换行符或文件结尾。
gets()函数 会读取整行输入行,直至遇到换行符,然后丢弃换行符,储存其余字符,并在字符末尾添加一个空字符使其成为C字符串。
(4)缓冲区数据溢出的问题
缓冲区溢出是指计算机向缓冲区内填充数据位数时超过了缓冲区本身的容量,溢出的数据覆盖在合法数据上。
以输入函数为例:
在我们输入的过程中,输入函数是从缓冲区中读入,缓冲区的数据是从键盘录入,经常会碰到一个问题,就是当有两个scanf函数相接时,我们在读入第一个scanf后以回车结束,这时候\n仍存在在缓冲区,就会导致在下一个scanf函数要读入字符类型时,错误的将\n存入待更改的变量,造成程序错误。
使用fflush(stdin)函数可以清空缓冲区的数据,将标准输入流刷新,以保证输入函数的正确使用。(在vs编译器下刷新不了)
(5)数组越界
在使用scanf函数进行字符串输入时有可能会侵占其他空间。
scanf在从键盘读入字符时是从scanf中传入的地址开始一直访问下一个元素的内存 , 碰见空格符或者回车符时才停止读入并存入结束符’\0’ , 这就有可能造成了一个在问题 , 访问非法内存 。如果所输字符数量大于字符数组的长度 , 当scanf将把字符存入字符数组的最后一个元素后 , scanf()还会继续往后访问内存 , 将接收的字符继续存入 , 但之后的内存是我们未申请的非法内存 , 会发生未知错误。
(6)getchar函数
函数声明:
int getchar(void);
标准输入函数
返回从键盘读取的字符,回车键结束
它的作用是从stdin流中读入一个字符,也就是说,如果stdin有数据的话不用输入它就可以直接读取了,第一次调用getchar()时,需要人工的输入,但是如果输了多个字符,以后的getchar()再执行时就会直接从缓冲区中读取了。
对于 scanf 函数,'\n' 会触发 scanf 读取输入缓冲区的内容,但遇到 '\n' 或空格 ' ' 会停止读取,而 getchar 会直接读取 '\n' 和空格。