C 字符串的输入输出

来源:互联网 发布:考试经文知乎 编辑:程序博客网 时间:2024/06/10 08:35

使用C语言编写程序时,很多时候需要处理从标准输入输入的字符串。

理论上讲有三种方法:

scanf("%s", str);
gets(str);                                   // vs2017中gets_s(str);

fgets(str, SIZE + 1, stdin);      // +1 是为了存放字符串结尾符'\0'


其中

str        : 一个char指针或者char数组名

SIZE    : 一个常量

stdin    :标准输入

首先要注意的问题是str应为一个char指针,还是一个char数组名。如果str为一个char指针,那么在从标准 输入读取数据时,将无法确定要读取的字节数。这是一个著名的漏洞,当用户输入超出函数使用的数组范围时将造成缓冲区溢出。因此,不能将str定义 为一个char指针,而要定义为一个数组名。


对于以上三个函数,输入字符串时有什么异同呢


当使用scanf函数时,如果在数组范围内有空格,那么第一个空格之后的字符将被忽略,仍然保留在缓存区。而且,scanf函数也不提供对写入数组的数据是否越界的检查。

#include<stdio.h>
#define SIZE 20void main(){    char str[SIZE]={0};    scanf("%s",&str); //输入 my name is c    printf("%s",str);}
输出结果为my

#include<stdio.h>
#define SIZE 10void main() {char str1[SIZE] = { 0 }, str2[SIZE] = { 0 }, str3[SIZE] = { 0 },str4[SIZE] = { 0 };scanf("%s%s%s%s", &str1, &str2, &str3, &str4); //输入 my name is cprintf("%s\n", str1);printf("%s\n", str2);printf("%s\n", str3);printf("%s\n", str4);}

输出为:

my

name

is 

c


当使用gets函数时,gets也不提供对写入数组的数据进行是否越界的检查。

#include<stdio.h>
#define SIZE 20void main() {char str[SIZE] = { 0 };gets_s(str); //输入 my name is cprintf("%s\n", str);}

输出:
my name is c


使用fgets函数时,只要第二个参数正好等于第一个参数传给它的数组的字节个数,那么fgets函数不会写出数组边界。

#include<stdio.h>
#define SIZE 10void main() {char str[SIZE] = { 0 };fgets(str,SIZE,stdin); //输入 my name is cprintf("%s\n", str);}
输出
my name i

字符串str的第十个字符是字符串结尾符'\0'

#include<stdio.h>#define SIZE 10void main() {char str[SIZE-1] = { 0 };fgets(str,SIZE+1,stdin); //输入 my name is cprintf("%s\n", str);}
输出

my name is 

发生了数组越界。

原创粉丝点击