鱼C论坛

 找回密码
 立即注册
查看: 1127|回复: 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[i]!='\0';i++){
                printf("%d ",str1[i]);        //将各个字符的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[i]!='\0';i++){
                printf("%d ",str1[i]);        //将各个字符的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 编辑
struct _iobuf {
    char *_ptr; //文件输入的下一个位置
    int _cnt; //当前缓冲区的相对位置
    char *_base; //指基础位置(即是文件的起始位置)
    int _flag; //文件标志
    int _file; //文件的有效性验证
    int _charbuf; //检查缓冲区状况,如果无缓冲区则不读取
    int _bufsiz; //

    char *_tmpfname; //临时文件名

        };
typedef struct _iobuf FILE;

红框

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

使用道具 举报

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

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

int main()
{
    char str[20];
    gets(str);
    printf("%s", check(str));
    return 0;
}
输入:
banana
输出:
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个字符,得到的结果是
#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[i]!='\0';i++){
                printf("%d ",str1[i]);        //将各个字符的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;
}

结果:
屏幕截图 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-9-23 07:32

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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