【9】自定义I/O函数s_gets

1、C语言库里的I/O函数

我们知道C语言库里自带很多的I/O函数(输入输出),例如:scanf、printf……这里我们重点讲输入函数
在这里插入图片描述

  • scanf()
    从第一个非空白字符开始,遇到空白字符(空行、空格、制表符、换行符)结束,其中字符串不包括空白字符。通过转化说明(例如%d)可以输入不同的数据类型,是一个优秀的“翻译家”。
  • getchar()
    读取一个字符
  • gets(int word[])
    读取整行输入,并存储字符和\0到words中,丢弃换行符/不检查溢出/默认从屏幕读入
  • fgets(int word[], int arrsize, stdin/stdout)
    读取整行输入,存储arrsize-1个字符和一个\0到word中,不丢弃换行符/检查溢出/会指明读入文件(如果读到第一个是\n则存储\n,然后停止读取)
  • gets_s(int word[], int arrsize)
    读取整行输入,存储arrsize-1个字符和一个\0到word中,丢弃换行符/检查溢出/默认从屏幕读入(如果>=arrsize则有可能导致程序终止)
  • s_gets()是我们自己定义一个加强版fgets()

2、自己定义一个加强版fgets():s_gets()

(1)几个输入函数的对比

前两个比较简单,重点是gets、fgets、gets_s这三个函数

①当字符数组没有超出数组大小时,上述函数都没有问题

②但是当输入字符串太长时

使用get不安全,有可能会擦除已有的数据导致程序终止;

使用fgets只会读取符合数组大小的字符串,多余的全部放回缓存区,有可能会保存了\n;

使用get_s虽然安全,但是程序会中止或退出由于fgets会存储\n。

③可以看出使用fgets比较方便并且安全快捷,唯一的问题就是fgets会保存\n而不是丢弃它,这个\n有时候会造成一点问题,故可以利用fgets来构造一个更加好的函数s_gets。

(2)具体代码

#define NUMBER 10
int main()
{
    char words[NUMBER];
    while (fgets(words, NUMBER, stdin) != NULL && words[0] != '\n')//1、保证输入成功,并且第一个字符不是/n
    {
        int i = 0;
        while (words[i] != '\n' && words[i] != '\0')//2、“是字符” == “中途输入就有\n”或“输完了自动加了\0”
        {
            i++;
zz        }
        if (words[i] != '\n')//3、将混杂的\n改变成为\0
        {
            words[i] = '\0';
        }
        else//4、即就是结尾\0了,将后面没有读取的舍弃
        {
            while (getchar() != '\n')
            {
                ;//5、或者替换成continue
            }
        }
    }
    return 0;
}

再改造成一个s_gets()函数

char* s_gets(char* st, int n)//存储数组首元素地址、存储字符大小
{
    char* ret_val;//返回值
    int i = 0;//数组下标
    ret_val = fgets(st, n, stdin);
    if (ret_val)//非NULL
    {
        while (st[i] != '\n' && st[i] != '\0')
        {
            i++;
        }
        if (st[i] == '\n')
        {
            st[i] = '\0';
        }
        else
        {
            while (getchar() != '\n')
                continue;
        }
    }
    return ret_val;
}

如果使用库函数strchar还能再整洁一点

//另外更加简短的方法
#include 
char* s_gets(char* st, int n)//存储数组首元素地址、存储字符大小
{
    char* ret_val;//返回值
    char* find;

    ret_val = fgets(st, n, stdin);
    if (ret_val)//非NULL,成功输入
    {
        find = strchar(st, '\n');
        if (find)//如果不是换行符就返回空指针
        {
            *find = '\0';
        }
        else
        {
            while (getchar() != '\n')
                continue;
        }
    }
    return ret_val;
}

你可能感兴趣的:(C语言刷题笔记,c语言,开发语言)