一.前言:如果想读入一个字符串,必须首先预留存储字符串的空间,然后才使用输入函数来获取合格字符串。
二.创建存储空间
要做的第一件事是建立一个空间用来存放字符串。不要指望计算机读取字符串时会自动计算字符串长度,并且为字符串分配空间。所以,字符串的空间必须人为分配:最简单的办法就是在声明中指出数组的大小。
例1: char *name;
scanf("%s",name);//错误
例2: char name[80];
scanf("%s",name);//正确
例1是个很常见的错误,并且大多数时候都不容易被发觉,错误原因在于指针name未初始化也没有分配动态内存,它可能指向任何地方。关于动态内存分配的问题可以查看《动态内存分配专题》。
三.字符串输入函数
1.gets()函数
1)实现原理
它读取换行符之前的所有字符,在这些字符后面加空字符' ',把这些字符串返回。然后读取换行符并将其丢
弃,这样下次读取就会在新的一行开始。
2)函数的构造
char *gets(char *s)
{
......
return s;
}
3)调用格式: gets(地址);
4)gets()函数通过两种方式获得输入:
a. 使用地址作为参数把输入字符串存储起来。
b. 使用关键字return 返回字符串的地址,这就意味着gets()必须返回一个指向char型的指针。
另一个返回值是当出错或遇到文件末尾,就会返回一个空指针NULL
请注意,gets()函数返回的指针与传给他的指针是同一个指针!
例 3:char name[80];
char *p;
printf("Input the name please ! ");
p = gets(name);
printf("%s! ",name);
printf("%s! ",p);
结果:Input the name please !
Tiantian
Tiantian!
Tiantian!
2.fgets()函数
1)函数的构造
char *fgets(char *s,int len,FILE *fp)
{
......
return s;
}
2)调用格式:fgets(地址,len,file);
gets()函数的一个不足时他不检查预留存储器是否能够容纳实际输入的数据,多出来的字符简单地溢出到相邻的
内存区。 fgets()函数就改进了这个问题,它让你指定最大读入的字符数。fgets()和gets()有三方面不同:
a.它需要第二个参数来说明最大读入字符数。它有两种结束方式,第一如果这个参数为n,fgets()就会读取最多
n-1个字符,第二读到一个换行符为止,由这两者中最先满足的那个来结束输入。
b.如果fgets()读到换行符,就会把它存到字符串里,而不是像gets()那样丢弃它。这样也造成了一个问题,每
次现实字符串时就会显示换行符。
c.第三个参数说明读哪个文件。当从键盘上读取数据时,可以使用stdin(standard input)作为该参数。
例4:char name[80];
char *p;
printf("Input your name please ! ");
p = fgets(name,80,stdin);
printf("%s! ",name);
printf("%s! ",p);
结果:Input the name please !
Tiantian
Tiantian
!
Tiantian
!
3.scanf()函数
1)构造函数
int scanf(char *s)
{
......
return count;//返回值是成功读取的项目数(不是字符个数)。当文件结束时返回一个EOF
}
2)调用格式:scanf("%s",地址);
scanf()和gets()主要的差别在于如何决定字符串何时结束。gets()函数倾向于获取字符串(注意字符串是允许
有空格的),当读到换行符时停止读入。而scanf倾向于获取字符(单词,不 允许有字符串),结束的方式有两
种:第一,当读到空白符(比如空格,制表符Tab,换行符),第二,制定了字段宽度,比如%10s。
例5:char name1[11],name2[11];
int count;
printf("Input 2 names please ! ");
count = scanf("%s %s",name1,name2);
printf("read %d names: %s and %s",count,name1,name2);
结果:Input 2 names please !
TT tian
read 2 names: TT tian
总结:根据所需输入的特点,用gets( )从键盘获取文本可能更好,因为它更容易被使用。如果每次只输入一个单词,最好用scanf()。