鱼C论坛

 找回密码
 立即注册
查看: 1050|回复: 7

[技术交流] 字符型数组的gets函数和puts函数的输入输出

[复制链接]
发表于 2021-12-12 11:20:01 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
在谭浩强的《C程序设计(第5版)》的 P158 对puts和gets进行了介绍。

/*
gets(字符数组)是从终端输入一个字符串到字符数组,并将该数组起始地址作为函数值。如:
gets(str);        //str是已定义的字符数组
在键盘输入:        computer
则将该字符组送给字符数组str(注意此处共送给数组9个字符,而非8个)。
*/

以上是书本原文。
很理所当然地,我认为这“第9个”字符应该就是 '\0' 而非 '\n' 。为了验证这个想法我就写下了以下代码:

#include <stdio.h>
#include <string.h>
int main(){
       
        char str1[30];
        int i;
       
        gets(str1);
       
        for(i=0;str1!='\0';i++){
                printf("%d ",str1);        //将各个字符的ASCII码打印出来
        }
       
        return 0;
}

在键盘上输入 123回车 这四个字符后,得到的结果是:

屏幕截图 2021-12-12 110744.png

只打印出了“123”这3个字符的ASCII码,看来想法可能是对的。
但是,最后这个回车是保留在缓冲区等待被接受?还是已经被接受作为'\0'输出了?
我为了找答案又写下了以下代码:

#include <stdio.h>
#include <string.h>
int main(){
       
        char str1[30],str2[30];
        int i,j;
       
        gets(str1);
        getchar();        //假设'\n'还停留在缓冲区,那么可以被这一行吃掉
        gets(str2);
       
        for(i=0;str1!='\0';i++){
                printf("%d ",str1);        //将各个字符的ASCII码打印出来
        }

        putchar('\n');

        for(j=0;str2[j]!='\0';j++){
                printf("%d ",str2[j]);        //将各个字符的ASCII码打印出来
        }

        //putchar('\n');
        //puts(str1);
        //putchar('\n');        可以随时修改

        puts(str2);       
       
        return 0;
}

在键盘上输入 123回车123 这7个字符之后会怎样?



想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-12-12 11:58:05 | 显示全部楼层
本帖最后由 jhq999 于 2021-12-12 12:00 编辑
  1. struct _iobuf {
  2.     char *_ptr; //文件输入的下一个位置
  3.     int _cnt; //当前缓冲区的相对位置
  4.     char *_base; //指基础位置(即是文件的起始位置)
  5.     int _flag; //文件标志
  6.     int _file; //文件的有效性验证
  7.     int _charbuf; //检查缓冲区状况,如果无缓冲区则不读取
  8.     int _bufsiz; //

  9.     char *_tmpfname; //临时文件名

  10.         };
  11. typedef struct _iobuf FILE;
复制代码

红框

红框
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-12-12 12:11:59 | 显示全部楼层
  1. #include <stdio.h>

  2. char* check(char* str){
  3.     for(int i = 0; ; i++){
  4.         if(str[i] == '\0') return "end with Null Character";
  5.         if(!str[i]) return "end without Null Character";
  6.     }
  7. }

  8. int main()
  9. {
  10.     char str[20];
  11.     gets(str);
  12.     printf("%s", check(str));
  13.     return 0;
  14. }
复制代码
输入:
  1. banana
复制代码
输出:
  1. end with Null Character
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-12-12 13:03:24 | 显示全部楼层

图片中“缓存区相对位置”中有个“\n”,意思是说这个 回车 还在缓存区中等待输出对吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-12-12 13:06:28 | 显示全部楼层

从输出结果来看,就是说str1的最后一个字符是'\0'对吧。但我想知道的是这个'\n'是到哪去了?是还留在缓存区?还是说被当成'\0'吃掉了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-12-12 13:16:46 | 显示全部楼层
在执行第二段代码(原来那个代码写错了,应该是下面这个)的时候。输入 123回车123 这7个字符,得到的结果是
  1. #include <stdio.h>
  2. #include <string.h>
  3. int main(){
  4.       
  5.         char str1[30],str2[30];
  6.         int i,j;
  7.       
  8.         gets(str1);
  9.         getchar();        // ① 假设'\n'还停留在缓冲区,那么可以被这一行吃掉
  10.         gets(str2);
  11.       
  12.         for(i=0;str1[i]!='\0';i++){
  13.                 printf("%d ",str1[i]);        //将各个字符的ASCII码打印出来
  14.         }

  15.         putchar('\n');       

  16.         for(j=0;str2[j]!='\0';j++){
  17.                 printf("%d ",str2[j]);        //将各个字符的ASCII码打印出来
  18.         }

  19.         //putchar('\n');
  20.         //puts(str1);
  21.         //putchar('\n');        可以随时修改

  22.         puts(str2);      
  23.       
  24.         return 0;
  25. }
复制代码


结果:
屏幕截图 2021-12-12 131208.png

很明显第一行输出了 str1 的三个字符(123)的ASCII码,但第二行只输出了 str2 的后两个字符(2和3)的ASCII码,而且通过打印的位置可以推出:
字符串str2里只有2和3两个字符(没有回车)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-12-12 13:22:45 | 显示全部楼层
kg120 发表于 2021-12-12 13:16
在执行第二段代码(原来那个代码写错了,应该是下面这个)的时候。输入 123回车123 这7个字符,得到的结果 ...

哦我知道了。。只要把注释标①的那一个getchar()删掉就可以得出结果了。
看来在输入str1时作为分隔符的回车键'\n'其实已经被处理好了
屏幕截图 2021-12-12 132002.png
屏幕截图 2021-12-12 132027.png

当输入str2的值的时候,回车键不会作为str2的第一个元素字符
但2楼的那个状态栏好像是显示回车键还在缓存区里,这里又让我很疑惑。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-12-12 14:22:45 | 显示全部楼层
kg120 发表于 2021-12-12 13:06
从输出结果来看,就是说str1的最后一个字符是'\0'对吧。但我想知道的是这个'\n'是到哪去了?是还留在缓存 ...

如图:
gets() 解说.jpg

评分

参与人数 1荣誉 +3 贡献 +1 收起 理由
kg120 + 3 + 1 谢谢

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-22 17:38

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表