一、格式化输入
格式化输入是指根据特定的格式从输入流中读取数据并存储到变量中。scanf函数就是用于读取标准输入流(stdin)的函数之一。
函数原型:int scanf(const char *format, …);
其中format参数是格式控制字符串,决定了读入数据的类型和格式,...是可变参数,根据format中指定的格式将相应数量和类型的参数传入。如:
int num; scanf("%d",&num);
上述代码中的format为"%d",表示读入一个十进制整数;第二个参数传入的是一个指向int类型变量num的指针,用于存储读入的整数。
除了%d外,有一些常见的格式控制符:
格式控制符 | 类型 | 读入数据 |
---|---|---|
%d | int | 十进制整数 |
%f | float、double | 浮点数 |
%c | char | 字符 |
%s | char* | 字符串 |
二、输入多个数据
scanf函数可以一次读入多个数据并分别存储到不同的变量中。可以在format中使用多个格式控制符,并在...中传入对应数量的变量地址。如:
int a,b; scanf("%d%d",&a,&b);
上述代码中,可以同时读入两个整数,并分别存储到变量a和变量b中。
三、输入时跳过空白字符
scanf函数默认会跳过空白字符(空格、换行、回车等),直到读入到非空白字符为止。这种行为称为“多余字符保留(extra characters remain)”。
例如,输入"123\n"并读入一个整数:
int num; scanf("%d",&num);
这时scanf函数会跳过'\n'这个字符,只读取数字部分。在读取完数字之后,如果输入缓冲区中还有字符,则这些字符会被留在输入缓冲区中,下一次读取输入流时会继续读入这些字符。
四、安全输入
使用scanf函数时需要注意安全性。如果输入数据不符合格式控制符指定的类型,则会导致结果无法预料,甚至可能引起程序崩溃。
为了安全输入,可以使用scanf函数的返回值。scanf函数返回成功读入的参数数量,可以根据这个值判断读入是否成功,并做出相应的处理。例如:
int num; if(scanf("%d",&num) != 1) { printf("输入的不是整数!"); }
如果scanf函数返回的值不等于1,说明读入的数据不是一个整数,此时输出提示信息。
五、使用scanf函数读入字符串
scanf函数可以使用%s格式控制符读入字符串。需要注意的是,如果输入的字符串中包含空格,则scanf函数会在第一个空格处停止读取,后面的字符则留在输入缓冲区中。可以使用scanf函数输入宽度来限制读入的字符串长度。如:
char str[20]; scanf("%19s",str); // 限制最大长度为19个字符
六、输入指定长度的数据
有时需要读入长度未知的数据,可以使用scanf函数的转换格式来读取指定长度的字符或者二进制数据。例如:
char str[10]; scanf("%10[^\n]",str); // 读取长度不超过10的一行字符串
上述代码中,%10[^\n]表示读取长度不超过10个字符的一行字符串,^[^\n]表示除了换行符外的任意字符都可以匹配。
七、scanf函数的错误处理
scanf函数可以接收格式控制符,但是,它并不会判断输入数据的有效性。所以在使用scanf函数时一定要注意“中脚炎(足)问题(garbage in,garbage out)”,即输入的数据可能包含有意外字符,这些字符可能会导致程序挂起,这可能是伏笔作为安全漏洞的存在风险。
因此,scanf函数还有些潜在的问题需要我们注意,例如:缓冲区溢出、格式串不匹配、行结束符等问题的缺陷。
备注:请注意如何处置溢出问题,使用可信的输入的逊确缺陷以防礙止相应的漏洞,保障系统的稳定性。