昨天我们说到怎么输入一个"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()&&getchar()_C

     输出是不是正常了?看来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()&&getchar()_C_02

        结果和想象中的一样,看来我们上面的推断没错,传入的指针和返还的指针是同一个指针。知道gets()之后我们再来看看运行上面这个程序,这一次,我们不输入Hello World,我们多输出两个单词看看,这样吧,我们就输入:Hello World,C/C++ program ,现在来看看他的输出情况吧:

gets()&&getchar()_C_03

       嗯,输出好像没问题,我们不妨在敲一下键盘看看:

gets()&&getchar()_C_04

       啊?怎么回事?为什么会出现这种情况呢?我想大家应该想到了,引起该异常主要来源来数组越界,因为我们声明的是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;

}

--------------------------------------

这个程序的输出和我们刚才的实例完全一样:

gets()&&getchar()_C_05

------------------------------------------

现在想必大家已经猜到和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++的编程教室