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

    文章

    553

    浏览量

    20284

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

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

收藏 人收藏

    评论

    相关推荐

    Matlab的字符串处理函数命令

    Matlab的字符串处理函数命令字符串处理函数名    功能描述    函数名&
    发表于 09-22 15:52

    matlab的一般字符串函数字符串比较命令

    matlab的一般字符串函数字符串比较命令一般字符串函数 Strings MATLAB中有关字符串
    发表于 09-22 15:59

    串口读取的字符串字符串输入控件输入字符串的差别

    发现很多时候串口读取的字符串字符串输入控件输入字符串虽然看着一样,但是要进行后续操作的话,却总是不一样的。大家有过这种感受吧,知道什么原
    发表于 06-06 11:44

    扫描字符串函数输入字符串格式问题

    使用扫描字符串函数时,如图中所示,提示输入字符串格式不符合预期。例子中格式字符串{%s},对输入
    发表于 08-27 10:25

    用labview一字符串输入(包含数字)如何变成输出纯字母类的新字符串

    想问一下,用labview一字符串输入(包含数字)如何变成输出纯字母类的新字符串 我想用公式节点去做,但要先把原
    发表于 10-19 00:23

    手把手教你Labview——“I Love Labview”字符拼接游戏学习字符串及操作

    串口通信、GPIB通信、TCP/IP通信等均需用到字符串相关操作,下面就跟着我一步步操作吧!一、添加4个“输入字符串”控件,分别重命名为“输入
    发表于 12-29 20:39

    labview新人请教字符串转换问题

    新人求问,我在字符串输入框中输入a,在字符串显示框中显示出字符“!”或其他标点符号,怎么实现呢?就像这样上边定义a为“!”或“?”下边可以测
    发表于 04-03 16:49

    如何将字符串输入顺序连接到字符串数组中?

    有一个字符串输入控件,每输入一个名称,点击按钮让其最终显示在“菜单式下拉列表”中,我尝试了使用“菜单式下拉列表”中属性节点“字符串[]”,但是发现
    发表于 07-27 19:17

    【LabVIEW懒人系列教程-小白入门】1.17LabVIEW之字符串的运用

    上期1.16作业讲解公式节点可以添加自定义输入输出,编写相应公式代码进行运算并输出值运行效果如下:今天讲解Labview字符串控件以及函数工具的简单运用《
    发表于 08-05 21:47

    字符串处理相关函数有哪些

    字符串处理相关函数有哪些?它们分别有何功能?
    发表于 09-10 07:16

    字符串处理函数的作用是什么

    / 字符串处理函数 / stract函数 字符串连接函数例:printf(“%s”, stract(str1, str2));strcpy(
    发表于 02-25 06:41

    C语言输入输出

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

    字符串函数重写练习

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

    c语言怎么用scanf输入字符串

    在C语言中,我们可以使用scanf函数来接收用户的输入。scanf函数有很多种用法,其中一种用法就是用来接收字符串。 要接收字符串,我们可以
    的头像 发表于 11-24 10:03 1461次阅读

    oracle中拼接字符串函数

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