`

C中字符串的输入输出及相关函数

 
阅读更多

//本节内容摘自对Stephen Prata的《C Primer Plus》第五版

 

一.字符串的输入

 

   如果想把一个字符串读到程序中,必须首先保留存储字符串的空间,然后使用输入函数来获取这个字符串。

   要想读入字符串,必须分配足够大的存储区来存放希望读入的字符串。

      char *name;

      scanf("%s",name);

这可能会通过编译器,但是在读入name的时候,name会覆盖程序中的数据和代码,并可能导致程序异常中止。这是因为scanf()会把读入的信息放入由参数给定的地址中,在这种情况下,参数是个未被初始化的指针,name可能指向任何地方。

    故在读入数据时要给定数据所占的存储空间,如:

int name;    char name[40];

二.输入函数:gets(),fgets(),scanf()

 

1.gets()

 

      gets() (代表get string),使用地址作为参数,它从系统的标准输入设备(通常是键盘)获得一个字符串。

因为字符串没有预订的长度,所以gets()需要知道输入何时结束。解决办法是读字符串直到遇到一个换行符(\n),按回车键可以产生这个字符。它读取换行符之前(不包括换行符)的所有字符,在这些字符后添加一个空字符(\0),然后把这个字符串交给调用它的程序。它将读取换行符并将其丢弃,这样下一次读取就会在新的行开始。

例:

char name[81]; /*分配空间*/

printf("Hi ,what is your name?");

gets(name);

printf("%s\n",name);

     返回值:如果读入正常,则返回的是读入字符串的地址(即一个指向char型的指针),如果出错或gets()遇到文件结尾,则返回一个空(或0)地址。这个空地址被称为空指针,并用stdio.h里定义的常量NULL来表示。

     因此gets()中还加入了一些错误检测,这是它可以很方便的以如下形式使用:

while(gets(name) != NULL)

这样的指令使您既可以检查是否到了文件结尾,有可以读取一个值。如果遇到了文件结尾,name中什么也不会读入。

     (顺便提一下,不要混淆空指针和空字符。空指针是一个地址,而空字符是一个char类型的数据对象,其值为0.数值上两者都可以用0表示,但他们的概念不同:NULL是一个指针,而0是一个char类型的常量)

 

2.fgets()

 

gets()的一个不足时它不检查预留存储区是否能够容纳时间输入的数据。多出来的字符简单的演绎出到相邻的内存区。fgets()函数改进了这个问题,它让您指定最大读入字符数。由于fgets()是为文件I/O而设           计的,在处理键盘输入时就不如gets()那么方便。fgets()和gets()有三个方面不同:

 

  • 它需要第二个参数来说明最大读入字符数。如果这个参数值为n,fgets()就会读取最多n-1个字符或者读完一个换行符为止,有这两者中最先满足的那个来结束输入。
  • 如果fgets()读到换行符,就会把它存到字符串里,而不是像gets()那样丢弃它。
  • 它还需要第三个参数来说明读哪一个文件。从键盘上读数据时,可以使用stdin作为该参数,这个标识符在stdio.h中定义。

 

        例:

char name[81];

char *ptr;

ptr = fgets(name,81,stdin);

printf("%s",ptr);

由于gets()不检查目标数组师傅能够容纳输入,所以不安全,几年前有人注意到操作系统代码使用gets(),于是他们利用这个弱点,用很长的输入覆盖操作系统的代码,从而发明了在UNIX网络上传播的“蠕虫”病毒。那些系统代码后来被不使用gets()的代码所代替。因此对与重要的编程,应该使用fgets()而不是gets().

 

3.scanf()函数

scanf()函数使用%s格式读入一个字符串。scanf()和gets()主要的差别在与他们如何决定字符串何时结束。scanf()更急于获取单词而不是获取字符串;而gets()函数会读取所有的字符,直到遇到第一 个换行符为止。scanf()使用两种方法决定输入结束。无论那种方法,字符串都是以遇到的第一个非空白字符开始。如果使用%s格斯,字符串读到(但不包含)下一个空白字符(空格,制表符或换行符)。如果 指定了字段宽度,比如%10s,scanf()会读入10个字符或知道遇到第一个空白字符,由二者中最先满足的哪一个终止输入。

                scanf()函数返回一个整数值,这个值是成功读取的项目数;或者当遇到文件结束时返回EOF。

 

       根据所需输入的特点,用gets()从键盘读取文本可能要更好,因为他更容易被使用,更快,且更简洁。scanf()主要用于以某种标准形式输入的混合类型数据的读取和转换。例如,如果每一个输入行都包含一种工具的名称,库存数量和单价,您就可以使用scanf();否则您必须在函数中自己处理输入错误的检验。如果希望以此值读入一个单词,最好使用scanf().

 

二.字符串的输出:puts(),fputs(),printf()

 

1.puts()函数

puts()函数使用很简单,只需要给出字符串参数的地址。

例:

char *name = "hellow wold";

puts(name);

与printf()不同,puts()函数显示字符串时自动在其后添加一个换行符。puts()输出时遇到空字符(\0)停止,所以应确保输出的字符串中有空字符。

 

2.fputs()函数

fputs()函数是gets()的面向文件版本。两者之间的主要区别:

 

  • fputs()需要两个参数来说明要写的文件。可以使用stdout作为参数来进行那个输出显示,stdout在stdio.h中定义
  • 与puts()不同,fputs()并不为输出自动添加换行符。

 

     注意:gets()丢掉输入里的换行符,但是puts()为输出添加换行符。另一方面,fgets()存储输入中的换行符,而fputs()也不为输出添加换行符。

        应把puts()和gets()结合使用,fputs()和fgets()结合使用。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics