C语言是一门广泛应用于操作系统、游戏开发以及嵌入式系统开发中的计算机编程语言,拥有强大的基础数据类型和结构类型,让开发者能够充分发挥计算机的计算能力。在C语言中,scanf( )是一种常用的输入函数。scanf( )函数采用格式字符串控制输入的格式,所以具有非常灵活的输入方式。下面我们就深入剖析C语言中的scanf用法,为大家详解格式化输入函数。
一、scanf( ) 函数的概述
scanf( ) 是C标准库中的一个函数,其目的是从指定的流 stream (例如,stdin、文件等)读取数据。函数原型如下所示:
```c
int scanf(const char *format, ...);
```
在该函数原型中,format与printf( ) 函数用法相同,是一个格式化的字符串,后面的三个省略号代表变参函数的部分,表示函数实际参数的个数不定,根据format字符串中的格式指令对应不同的数据类型和数量。
格式字符串中的格式指令用来控制输入文件中的输入数据格式。C语言中的格式指令形式多样,可以用于整数、浮点数、字符、字符串等基础数据类型及它们的指针类型,也可以对自定义类型的数据进行输入、输出。
对于scanf( )函数,如果成功读取到输入数据,并且数据类型与字符格式字符串中的格式控制符匹配,则会将输入数据写入可变数量的参数列表中并返回成功读取的参数数量;否则,返回0。
二、常见的scanf用法
在使用scanf( )函数时,有几点需要注意:
1. 在使用格式字符串时,应该在格式符前加上修饰符。这些修饰符控制数据类型和打印格式。例如,修饰符 %d 通常在整数格式指令前面使用,代表进一步确定其类型及位宽;而 %f 及 %e 则用于浮点数。
2. 格式字符串可以包含空格、制表符和换行符。空格和制表符在格式字符串中的作用是跳过输入中的空格和制表符,并将光标移动到下一个字的开头。换行符的处理行为与空格相同。
3. 在读取字符串时,需要注意缓冲区溢出问题。由于scanf( )函数中使用的缓冲区大小有限,如果输入的字符串太长,则会导致缓冲区溢出,最终使程序崩溃。解决方式也很简单,只需要用字符数占用的缓冲区大小来限制输入的字符数。
4. 使用scanf( )输入数据时,应遵循匹配输入格式的原则。如果格式被打乱,可能会导致未定义的行为。
以下是几个常见的使用scanf( )的场景和技巧。
1. 读取整型数
在C语言中,格式字符串用于读取整型数。下面是一个读取整型数并打印的样例程序:
```c
#include
int main()
{
int num;
printf("请输入一个整数:\n");
scanf("%d",&num);
printf("输入的整数是:%d\n",num);
return 0;
}
```
在这个程序中,输入的整数是 %d,表示输入的是十进制的整数,而 &num 是 %d 的修饰符,其作用是告诉scanf( )函数把用户输入的值传递给变量num。
2. 读取浮点数
格式字符串用于读取实数。下面是一个读取浮点数并打印的样例程序:
```c
#include
int main()
{
float x;
printf("请输入一个浮点数:\n");
scanf("%f", &x);
printf("浮点数为: %f\n", x);
return 0;
}
```
在这个程序中,%f 修饰符是格式字符串的一部分,它表示以浮点数格式输入。 &x 是格式控制字符串中的修饰符,它指示将值写入指定的单精度浮点型变量中。
3. 读取字符数据
除了读取数字,还可以使用scanf( )函数来读取一个字符。下面是一个读取字符变量并打印的样例程序:
```c
#include
int main()
{
char ch;
printf("请输入要输入的字符:\n");
scanf("%c", &ch);
printf("请输入的字符为: %c\n", ch);
return 0;
}
```
scanf函数中 %c 用于输入单个字符,字符被存储在单个字符变量中,变量需要用地址运算符 & 来读取。
4. 读取字符串
由于无法直接在scanf( )函数中打印字符串,如果读取字符串,需要在程序中使用一个字符数组来存储字符串,并将该数组作为scanf( )函数的参数之一。以下是读取字符串的样例程序:
```c
#include
int main()
{
char str[100];
printf("请输入字符串:\n");
scanf("%s", str);
printf("输入的字符串是: %s\n", str);
return 0;
}
```
在这个程序中,“%s”是格式字符串的一部分,表示字符串格式。 str 是储存输入的字符串的字符数组。
5. 读取多个数据
除了读取数字或字符串,还可以从输入中读取多个数据。下面的程序读取三个数字并求和:
```c
#include
int main()
{
int a,b,c,d;
printf("请输入三个数字,用空格隔开:\n");
scanf("%d %d %d",&a,&b,&c);
d=a+b+c;
printf("数字的和是:%d\n", d);
return 0;
}
```
在这个程序片段中,可以看到scanf函数中的修饰符使用了一种新的方式,其中每个整数以及它们之间的空格都成为scanf函数的参数。
三、scanf( )函数的错误处理
scanf( )函数的错误处理更为复杂,因为可能会遇到多种错误。以下是几种常见错误的处理方式:
1. 输入数字时,如果用户输入了非数字字符,则会导致错误,这时应该使用“%*”修饰符忽略无效字符,并将光标移动到下一个有效字符的开头,然后提示用户重新输入。
2. 如果读取字符串时,字符串中的字符数超过分配的内存大小,则会导致缓冲区溢出。为了避免溢出,可以在调用scanf()函数时限制格式控制字符串读取字符的数量,或者使用fgets()函数代替scanf()函数进行字符串的输入。
3. 当scanf函数访问指针时,如果指针未初始化,则会导致未定义的行为。未初始化的指针应该初始化后再使用。
4. 如果输入中出现了超长值,则scanf()函数可能会报告EINTR错误。解决方法是关闭输入流并重启程序。
结论
scanf( )函数在C语言中是一种常见的、功能强大的输入函数,可用于读取整数、浮点数、字符和字符串,以及使用“格式化输出控制”对输入的格式进行控制。然而,如上所述,在使用scanf( )函数时还需要注意一些技巧和注意事项。
在编写C程序时,深入了解scanf( )函数的使用可以帮助我们更好地实现程序功能,并且可以有效避免一些常见的错误。希望本文对读者有所帮助,让读者更加深入地理解scanf( )函数的使用,并掌握其技巧,为日后的程序开发工作提供参考。