昨天我们说到怎么输入一个"Hello world"然后让printf完整打印出来,但是失败了,今天我们来尝试另外两个函数,gets()和getchar(),还是老规矩,我们用一个实例来引入主题:
----------------------------------
#include <stdio.h>
int main()
{
char name[20];
printf("请输入字符串:\n");
gets(name);
printf("%s.\n",name);
getchar();
return 0;
}
--------------------------------------
运行程序后,输入Hello World,看看输出的会是什么?
输出是不是正常了?看来gets()这个函数果然是能够满足我们要求的,那么这个原型是什么呢?我们不妨来看一下MSDN是怎么写的:
char *gets( char *buffer );
MSDN是这么声明的,从这个声明我们可以推断出gets()应该返回一个指向char的指针,再从我们上面的实例,我们不难推断出这个函数返回的指针和传递给他的是同一个指针,所以他的定义应该像是这样:
----------------------------------
char *gets( char *buffer )
{
……
return (buffer);
}
------------------------------------
大家可能还在怀疑上面的定义是否正确,好吧,我们来验证一下,我们将函数修改一下,声明一个char指针,然后用gets(name)的返回值初始化这个指针。
-------------------------------------
#include <stdio.h>
int main()
{
char name[20];
char* ptr;
printf("请输入字符串:\n");
ptr = gets(name);
printf("name = %s.\n",name);
printf("ptr = %s.\n",ptr);
getchar();
return 0;
}
--------------------------------------
现在我们再来看看ptr到底等于什么:
结果和想象中的一样,看来我们上面的推断没错,传入的指针和返还的指针是同一个指针。知道gets()之后我们再来看看运行上面这个程序,这一次,我们不输入Hello World,我们多输出两个单词看看,这样吧,我们就输入:Hello World,C/C++ program ,现在来看看他的输出情况吧:
嗯,输出好像没问题,我们不妨在敲一下键盘看看:
啊?怎么回事?为什么会出现这种情况呢?我想大家应该想到了,引起该异常主要来源来数组越界,因为我们声明的是name[20],但是我们却输入的字符已经超过了20,虽然能够正常输出,但是却造成了数组越界,所以当程序结束回收内存的时候就抛出了这个异常。
说到底,造成该类异常的主要原因还是在于gets()这个函数的不安全,为了避免该类事情的发生,c语言引入了fgets()。
----------------------------------------
和gets()比起fgets()确实安全得多,但是在处理键盘输入时,fgets()却没有gets()方便,毕竟fgets()主要还是为文件读取而设定的,但是还是可以用来读取键盘输入,现在我们来看看fgets()的声明:
char *fgets( char *bufffer, int n,FILE *stream );
fgets()的第一个参数和gets()的参数一样,第二个参数n表示读取字符的最大数,至于第三个参数,是转为文件而设定,指明需要读取的文件,如果要读取键盘的输入,这个参数为:stdin,stdin在头文件stdio.h里声明,所以要使用stdin,只需包含stdio.h头文件即可。我们将上面的程序修改一下来看看:
-------------------------------------
#include <stdio.h>
int main()
{
char name[20];
char* ptr;
printf("请输入字符串:\n");
ptr = fgets(name,20,stdin);
printf("ptr = %s,name = %s.\n",ptr,name);
return 0;
}
--------------------------------------
大家可以自己尝试运行一下,这一次可以完美运行了,所以建议大家在读取键盘输入的时候尽量使用fgets()。
--------------------------------------
和gets()相对应的是puts(),我们再将上面的例子修改一下,如下所示:
-------------------------------------
#include <stdio.h>
int main()
{
char name[20];
char* ptr;
printf("请输入字符串:\n");
ptr = gets(name);
puts(name);
return 0;
}
--------------------------------------
这个程序的输出和我们刚才的实例完全一样:
------------------------------------------
现在想必大家已经猜到和fgets()对应的是fputs(),fputs()是puts()的文件版本,他的声明像这样:
int fputs( const char *buffer, FILE *stream );
fputs()需要第二参数,可以使用stdout(standard output)来作为输出参数 ,我们将上面的程序修改一下,如下:
-------------------------------------
#include <stdio.h>
int main()
{
char name[20];
char* ptr;
printf("请输入字符串:\n");
ptr = fgets(name,20,stdin);
fputs(name,stdout);
return 0;
}
--------------------------------------
该程序的运行结果和上面的一样,但安全性却比上面的要高,大家可以自己尝试一下吧。
现在总结一下三个标准输入函数:
scanf():更基于获取单词(get word)而不是获取字符串,他在遇到第一个空格时结束读取。
gets():顾名思义,他就是get string,所以他会连续获取一连串的字符,包括标点符号和空格,但是会在遇到换行符'\n'时结束读取。
fgets():f当然表示file,所以他是gets()的文件版本。
三个标准输出函数:
printf():标准格式化输出,功能强大,效率不俗,仅次于puts()。
puts():效率最高的输出函数,但只能配合gets()使用,而且只能用于输出字符串。
fputs():puts()的文件版本。
--------------------------
还有一对输入和输出函数:getchar()和putchar(),由于今天太晚了,就先不说这两函数了,明天再给大家说说这两个函数,看名字我想大家可能已经猜到这两个函数是用于什么的了。
转自公众号: C/C++的编程教室