0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

AGk5_ZLG_zhiyua 来源:未知 作者:佚名 2017-09-14 11:52 次阅读

周立功教授数年之心血之作《程序设计与数据结构》,电子版已无偿性分享到电子工程师与高校群体,在公众号回复【程序设计】即可在线阅读。书本内容公开后,在电子行业掀起一片学习热潮。经周立功教授授权,本公众号特对本书内容进行连载,愿共勉之。

第一章为程序设计基础,本文为1.8.2 字符串常量第二点:字符串的输入输出。

(1)scanf()函数和gets()函数

scanf()函数

在读取字符串时,scanf()和转换格式符%s只能读取一个单词,比如:

scanf("%s\n", str);

在scanf函数调用中,不需要在str前添加&,因为str是数组名,编译器在将它传递给函数时,会将它当作指针来处理。调用时,scanf函数会跳过空字符,然后读入字符并存储到str中,直到遇到空字符为止,scanf函数始终会在字符串末尾存储一个空字符。

gets()函数

在程序中经常要读取一整行输入,而不仅仅是一个单词,gets()就是用于处理这种情况的。它读取整行输入直至遇到换行符,然后丢弃换行符存储其余字符,并在这些字符的末尾添加一个空字符使其成为一个字符串。它经常和puts()配对使用,该函数用于显示字符串,并在末尾添加换行符。即gets()是从标准输入设备中输入若干个字符,并保存到参数s指向的字符数组中,直到文件结束或读到一个换行符。换行符将被丢弃,在输入最后一个字符后会立即写入一个结束符'\0'。其函数原型如下:

char *gets(char *s);

其中的s指向保存输入字符串的内存空间,如果gets()成功地获得了字符串,则返回s,否则返回NULL。比如,通过命令行输入一个字符'9',但'9'不是整数9,如果将'9'-'0',则会得到整数9。即:

char cStr[256];

int cmdNum;

cmdNum = getchar() - '0';

gets(cStr); //清空缓冲区

如果将数组作为参数传递,则传递的是指向数组首元素的指针,当gets()作为被调用函数时,则完全不知道数组究竟有多大,而调用者又不能向gets()传递缓冲区的大小,因此gets()无法检查数组的长度。显然必须有足够的空间保存输入的字符串,否则可能出现莫名其妙的问题。如果你故意将尺寸很大的数据传递给gets(),就可以达到数组越界且改写返回地址的目的。1988年名震互联网的“互联网蠕虫”病毒,就是利用了gets()的这个弱点。

由于gets()的不安全行为造成了隐患,因此制定C11标准的委员采取了强硬的态度,直接从标准中废除了gets()函数。不妨自己编写一个输入函数,假设函数不会跳过空字符,在第一个换行符(不存储到字符串中)处停止读取,且忽略额外的字符。其函数原型如下:

int readLine(char str[], int n);

readLine()函数主要由一个循环构成,只要str中还有空间,此循环就会调用getchar()函数逐个读入字符并将它存储在str中,在读入换行符时循环终止,详见程序清单 1.40。

程序清单 1.40 readLine()函数的实现

1 int readLine(char str[], int n)

2 {

3 int ch, i = 0;

4

5 while((ch = getchar()) != '\n')

6 if(i < n)

7 str[i++] = ch;

8 str[i] = '\0';

9 return 0;

10 }

(2)printf()函数和puts()函数

printf()函数

转换格式符s%允许printf()写字符串,与puts不同的是,printf()不会自动地在每个字符串的末尾加上一个换行符,因此必须在参数中指明应该在哪里使用换行符。比如:

char str[] = "hello world";

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

printf()会逐个写字符串中的字符,直到遇到空字符为止。如果只想显示字符串的一部分,可以使用转换格式符%.ps,这里的p是显示的字符数量。比如,显示hello:

printf("%.5s\n", str);

puts()函数

虽然printf()用起来比较复杂,但可以打印多个字符串。除了printf(),C标准库还提供了puts(),其函数原型如下:

int puts(const char *s);

其中,s为指定输出的字符串,puts()函数将参数s指向的字符串输出到标准输出设备中,但不输出结束符'\0'。在输出字符串后,puts()函数会多输出一个换行符'\n',然后通过标准输出设备显示指定的字符串。如果显示成功,则返回0,否则返回预定义常量EOF。puts()如何知道在何处停止呢?该函数在遇到空字符时就停止输出,所以必须确保有空字符。

(3)fgets()函数和fputs()函数

fgets()函数

fgets()和fputs()分别是gets()和puts()针对文件的定制的版本,fgets()通过第2个参数限制读入的字符数来解决溢出的问题,该函数专门用于处理文件输入。如果第2个参数的值是n,那么fgets()将读入n-1个字符,或遇到第1个换行符为止。如果读到一个换行符将它存储在字符串中,这点与gets()不同,gets()会丢弃换行符。

fgets()的第1个参数与gets()一样,也是存储输入位置的地址(char *类型),第2个参数是一个整数,表示待输入字符串的大小,最后一个参数是文件指针,指定待读取文件。如果读入从键盘输入的数据,则以标准输入stdin作为参数,该标识定义在stdio.h中。其调用示例如下:

fgets(buf, STLEN, fp);

其中,buf是char类型数组的名称,STLEN是字符串的大小,fp是指向FILE的指针。以上面的gets()为例,fgets()读取输入直到第1个换行符的后面,或读到文件结尾,或读取STLEN-1个字符,然后fgets()在末尾添加一个空字符使之成为一个字符串,字符串的大小是其字符数加上一个空字符。如果fgets()在读到字符上限之前已经读完一整行,它会将表示行结尾的换行符放在空字符前面。fegts()在遇到EOF时将返回NULL,因此可以利用这一机制检查是否到达文件结尾。如果未遇到EOF,则返回它的地址。

fgets()存储换行符有好处也有坏处,坏处是你可能不想将换行符存储在字符串中,这样的换行符会带来一些麻烦。好处是对于存储的字符串而言,检查末尾是否有换行符可以判断是否读取了一整行。如果不是一整行,则要妥善处理一行中剩下的字符。

首先,如何处理换行符?一个方法是在已经存储的字符串中查找换行符,并将其替换成空字符。假设\n在st中:

while(st[i] != '\n' )

i++;

st[i] = '\0';

其次,如果仍有字符串留在输入行怎么办?一个可行的办法是,如果目标数组装不下一整行输入,就丢弃那些多出的字符。即读取但不存储输入,包括\n:

while(getchar() != '\0')

continue;

为何要丢弃输入行中余下的字符?因为输入行中多出来的字符会留在缓冲区中,成为下一次读取语句的输入。比如,如果下一条读取语句要读取的是double类型的值,就可能导致程序崩溃,而丢弃输入行余下的字符是为了保证读取语句与键盘输入同步。既然没有这样的函数,那么就创建一个,s_gets()函数详见程序清单 1.41。

程序清单1.41 s_gets()函数

1 char * s_gets(char *st, int n)

2 {

3 char *ret_value;

4 int i = 0;

5

6 ret_value = fgets(st, n, stdin);

7 if(ret_value){

8 while(st[i] != '\n' && st[i] != '\0')

9 i++;

10 if(st[i] == '\n')

11 st[i] = '\0';

12 else

13 while(getchar() != '\0')

14 continue;

15 }

16 return ret_value;

17 }

如果fgets()返回NULL,说明读到文件结尾或出现读取错误,s_gets()跳过了这个过程。其中的循环:

while(st[i] != '\n' && st[i] != '\0')

i++;

遍历字符串,直到遇到换行符或空字符。如果先遇到换行符,下面的if语句将其替换成空字符;如果先遇到空字符,else部分便丢弃输入行的剩余字符,然后返回与fgets()相同的值。

尽管s_gets()用于替换fgets()已经有了很大的改进,但还是不完美。如果遇到不合适的输入时,它毫无反应。它丢弃多余的字符时,也不通知程序也不告知用户,请读者完善。

fputs()函数

由于fgets()将换行符放在字符串的末尾(假设输入行不溢出),通常要与fputs()配对使用,除非该函数不在字符串末尾添加换行符。

fputs()函数接受两个参数:第1个是字符串的地址,第2个是文件指针,指明要写入的文件,该函数根据传入地址找到的字符串写入指定的文件中。如果要显示在计算机显示器上,应使用标准输出stdout作为参数。和puts()不同的是,puts()在打印字符串时,不会在其末尾添加换行符。其调用示例如下:

fputs(buf, fp);

其中,buf是字符串的地址,fp用于指定目标文件。注意,gets()丢弃输入中的换行符,但puts()在输出中添加换行符。而另一方面,fgets()保留了输入中的换行符,fputs()在输出中不会添加换行符。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 字符串
    +关注

    关注

    1

    文章

    578

    浏览量

    20506

原文标题:周立功:字符真正价值在于形成字符序列——字符串的输入输出

文章出处:【微信号:ZLG_zhiyuan,微信公众号:ZLG致远电子】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    字符串函数测试学习工程

    字符串函数测试学习工程
    发表于 07-01 16:38 6次下载

    Labview之字符串长度函数

    Labview之字符串长度函数,很好的Labview资料,快来下载学习吧。
    发表于 04-19 10:43 0次下载

    C语言的字符串处理函数

    指针是神奇的,指向整型的指针int *p1,可以操作整型数组int a[];指向字符型的指针char *p2,可以操作字符数组(字符串)char str[];更灵活的是,在函数的传递中
    发表于 07-24 17:37 4次下载
    C语言的<b class='flag-5'>字符串</b>处理<b class='flag-5'>函数</b>

    LabVIEW的常用字符串操作教程免费下载

    字符串操作与信息的保存和显示密不可分,而字符串操作运用也是LabⅥEW程序设计的一个难点,因此熟练使用字符串操作函数是使用LabⅥEW进行编程所必备的能力之
    发表于 08-21 14:51 26次下载
    LabVIEW的常用<b class='flag-5'>字符串</b>操作教程免费下载

    C语言编程字符串函数汇总资源下载

    C语言编程字符串函数汇总资源下载
    发表于 04-15 16:18 9次下载
    C语言编程<b class='flag-5'>字符串</b><b class='flag-5'>函数</b>汇总资源下载

    C语言输入输出

    不对的地方请指出。1. 标准输入输出函数getchar():读入一个字符 putchar():输出一个字符 gets():读
    发表于 12-14 18:52 3次下载
    C语言<b class='flag-5'>输入输出</b>

    字符串函数重写练习

    字符串函数重写练习:字符串比较、字符串拼接、字符串查找、字符串拷贝、内存比较、内存拷贝、内存初始
    的头像 发表于 05-05 15:02 1990次阅读

    C语言总结_字符串函数封装练习

    字符串函数重写练习:字符串比较、字符串拼接、字符串查找、字符串拷贝、内存比较、内存拷贝、内存初始
    的头像 发表于 08-14 09:42 993次阅读

    C语言_字符串与指针的练习

    这篇文章涉及到字符串与指针知识点的相关练习。浮点数与字符串互转、字符串拷贝、字符串比较、指针交换变量、指针优先级、数据类型强制转换、内存拷贝
    的头像 发表于 08-14 09:51 1484次阅读

    python字符串有哪些特定方法

    python字符串序列操作也适用于列表和元组。 python字符串还有独有方法,即字符串对象的函数,其他对象不可调用,只有字符串对象可
    的头像 发表于 02-23 15:02 703次阅读

    字符串相关知识

    TCL 中的数据类型只有一种:字符串。这些字符串可以是字母、数字、布尔值、标点符号等特殊字符的组合。在某些特殊命令的作用下,字符串可以向其他数据类型转换。下面将系统的讲解或回顾下
    的头像 发表于 03-29 11:41 1145次阅读

    MySQL替换字符串函数REPLACE

    MySQL是目前非常流行的开源数据库管理系统之一,它具有强大的功能和性能。其中之一的字符串函数REPLACE,可以用于替换字符串中的指定字符字符串
    的头像 发表于 11-30 10:44 1545次阅读

    oracle中拼接字符串函数

    在Oracle中,我们可以使用 CONCAT 函数来拼接字符串。CONCAT 函数接受两个参数,它将这两个参数连接起来并返回相应的字符串结果。 语法示例: CONCAT(string1
    的头像 发表于 12-06 09:49 2905次阅读

    labview中常用的字符串函数有哪些?

    在LabVIEW中,常用的字符串函数广泛覆盖了对字符串的各种操作,包括但不限于格式化、搜索、替换、连接、计算长度等。以下是一些常用的字符串函数
    的头像 发表于 09-04 15:43 665次阅读

    labview字符串如何转换为16进制字符串

    在LabVIEW中,将字符串转换为16进制字符串是一个常见的需求,尤其是在处理数据通信和硬件接口时。LabVIEW提供了多种方法来实现这一转换,包括使用内置函数、编写VI(Virtual
    的头像 发表于 09-04 15:54 2296次阅读