kg120 发表于 2021-12-12 11:20:01

字符型数组的gets函数和puts函数的输入输出

在谭浩强的《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;
        int i;
       
        gets(str1);
       
        for(i=0;str1!='\0';i++){
                printf("%d ",str1);        //将各个字符的ASCII码打印出来
        }
       
        return 0;
}

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



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

#include <stdio.h>
#include <string.h>
int main(){
       
        char str1,str2;
        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!='\0';j++){
                printf("%d ",str2);        //将各个字符的ASCII码打印出来
        }

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

        puts(str2);       
       
        return 0;
}

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



jhq999 发表于 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;

傻眼貓咪 发表于 2021-12-12 12:11:59

#include <stdio.h>

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

int main()
{
    char str;
    gets(str);
    printf("%s", check(str));
    return 0;
}输入:banana输出:end with Null Character

kg120 发表于 2021-12-12 13:03:24

jhq999 发表于 2021-12-12 11:58


图片中“缓存区相对位置”中有个“\n”,意思是说这个 回车 还在缓存区中等待输出对吗?

kg120 发表于 2021-12-12 13:06:28

傻眼貓咪 发表于 2021-12-12 12:11
输入:输出:

从输出结果来看,就是说str1的最后一个字符是'\0'对吧。但我想知道的是这个'\n'是到哪去了?是还留在缓存区?还是说被当成'\0'吃掉了

kg120 发表于 2021-12-12 13:16:46

在执行第二段代码(原来那个代码写错了,应该是下面这个)的时候。输入 123回车123 这7个字符,得到的结果是
#include <stdio.h>
#include <string.h>
int main(){
      
      char str1,str2;
      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!='\0';j++){
                printf("%d ",str2);      //将各个字符的ASCII码打印出来
      }

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

      puts(str2);      
      
      return 0;
}

结果:


很明显第一行输出了 str1 的三个字符(123)的ASCII码,但第二行只输出了 str2 的后两个字符(2和3)的ASCII码,而且通过打印的位置可以推出:
字符串str2里只有2和3两个字符(没有回车)

kg120 发表于 2021-12-12 13:22:45

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

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



当输入str2的值的时候,回车键不会作为str2的第一个元素字符
但2楼的那个状态栏好像是显示回车键还在缓存区里,这里又让我很疑惑。。

傻眼貓咪 发表于 2021-12-12 14:22:45

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

如图:
页: [1]
查看完整版本: 字符型数组的gets函数和puts函数的输入输出