C //练习 8-3 设计并编写函数_flushbuf、fflush和fclose。

这篇具有很好参考价值的文章主要介绍了C //练习 8-3 设计并编写函数_flushbuf、fflush和fclose。。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

C程序设计语言 (第二版) 练习 8-3

练习 8-3 设计并编写函数_flushbuf、fflush和fclose。

注意:代码在win32控制台运行,在不同的IDE环境下,有部分可能需要变更。
IDE工具:Visual Studio 2010

 文章来源地址https://www.toymoban.com/news/detail-816160.html

代码块:
#include <fcntl.h>
#include <stdarg.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/syscall.h>

#ifdef NULL
#undef NULL
#endif

#define NULL 0
#define EOF (-1)
#define BUFSIZ 1024
#define OPEN_MAX 20

typedef struct _iobuf {
    int cnt;
    char *ptr;
    char *base; 
    int flag; 
    int fd; 
} FILE;

extern FILE _iob[OPEN_MAX];

#define stdin   (&_iob[0])
#define stdout  (&_iob[1])
#define stderr  (&_iob[2])

enum _flags {
    _READ = 01,
    _WRITE = 02,
    _UNBUF = 03, 
    _EOF = 010, 
    _ERR = 020, 
};

int _fillbuf(FILE *);
int _flushbuf(int, FILE *);

#define feof(p)     (((p)->flag & _EOF) != 0)
#define ferror(p)   (((p)->flag & _ERR) != 0)
#define fileno(p)   ((p)->fd)

#define getc(p) (--(p)->cnt >= 0 ? (unsigned char) *(p)->ptr++ : _fillbuf(p))

#define putc(x, p) (--(p)->cnt >= 0 ? *(p)->ptr++ = (x) : _flushbuf((x), p))

#define getchar()   getc(stdin)
#define putchar(x)  putc((x), stdout)

#define PERMS 0666

FILE *fopen(char *name, char *mode){
    int fd;
    FILE *fp;

    if (*mode != 'r' && *mode != 'w' && *mode != 'a')
        return NULL;

    for (fp = _iob; fp < _iob + OPEN_MAX; fp++)
        if ((fp->flag & (_READ | _WRITE)) == 0)
            break;

    if(fp >= _iob + OPEN_MAX)
        return NULL;

    if (*mode == 'w')
        fd = creat(name, PERMS);
    else if (*mode == 'a') {
        if ((fd = open(name, O_WRONLY, 0)) == -1)
            fd = creat(name, PERMS);
        lseek(fd, 0L, 2);
    } else
        fd = open(name, O_RDONLY, 0);

    if (fd == -1)
        return NULL;

    fp->fd = fd;
    fp->cnt = 0;
    fp->base = NULL;
    fp->flag = (*mode == 'r') ? _READ : _WRITE;
    return fp;
}

int _fillbuf(FILE *fp) {
    int bufsize;

    if ((fp->flag & (_READ | _EOF | _ERR)) != _READ)
        return EOF;

    bufsize = (fp->flag & _UNBUF) ? 1: BUFSIZ;

    if (fp->base == NULL)
        if ((fp->base = (char *) malloc(bufsize)) == NULL)
            return EOF;

    fp->ptr = fp->base;
    fp->cnt = read(fp->fd, fp->ptr, bufsize);

    if (--fp->cnt < 0) {
        if (fp->cnt == -1)
            fp->flag |= _EOF;
        else
            fp->flag |= _ERR;
        fp->cnt = 0;
        return EOF;
    }

    return (unsigned char) *fp->ptr++;
}

int _flushbuf(int c, FILE *f){
    int num_written, bufsize;
    unsigned char uc = c;

    if ((f->flag & (_WRITE | _EOF | _ERR)) != _WRITE) {
        return EOF;
    }

    if(f->base == NULL && ((f->flag & _UNBUF) == 0)){
        if ((f->base = (char*)malloc(BUFSIZ)) == NULL){
            f->flag |= _UNBUF;
		}
        else {
            f->ptr = f->base;
            f->cnt = BUFSIZ - 1;
        }
    }

    if(f->flag & _UNBUF){
        f->ptr = f->base = NULL;
        f->cnt = 0;
        if (c == EOF) {
            return EOF;
        }
        num_written = write(f->fd, &uc, 1);
        bufsize = 1;
    }
	else{
        bufsize = (int)(f->ptr - f->base);
        num_written = write(f->fd, f->base, bufsize);
        f->ptr = f->base;
        f->cnt = BUFSIZ - 1;
    }

    if (num_written == bufsize)
        return c;
    else {
        f->flag |= _ERR;
        return EOF;
    }
}

FILE _iob[OPEN_MAX] = {
    { 0, (char *) 0, (char *) 0, _READ, 0 },
    { 0, (char *) 0, (char *) 0, _WRITE, 1 },
    { 0, (char *) 0, (char *) 0, _WRITE | _UNBUF, 2 }
};

int flushbuf(int c, FILE *f){
    int num_written, bufsize;
    unsigned char uc = c;

    if ((f->flag & (_WRITE|_EOF|_ERR)) != _WRITE)
        return EOF;
    if (f->base == NULL && ((f->flag & _UNBUF) == 0)) {
        if ((f->base = (char*)malloc(BUFSIZ)) == NULL)
            f->flag |= _UNBUF;
        else{
            f->ptr = f->base;
            f->cnt = BUFSIZ - 1;
        }
    }
    if(f->flag & _UNBUF){
        f->ptr = f->base = NULL;
        f->cnt = 0;
        if (c == EOF)
            return EOF;
        num_written = write(f->fd, &uc, 1);
        bufsize = 1;
    }
	else{
        if (c != EOF)
            *f->ptr++ = uc;
        bufsize = (int)(f->ptr - f->base);
        num_written = write(f->fd, f->base, bufsize);
        f->ptr = f->base;
        f->cnt = BUFSIZ - 1;
    }
    if (num_written == bufsize)
        return c;
    else {
        f->flag |= _ERR;
        return EOF;
    }
}

int fflush(FILE *f) {
    int retval;
    int i;

    retval = 0;
    if (f == NULL) {
        for (i = 0; i < OPEN_MAX; i++) {
            if ((_iob[i].flag & _WRITE) && (fflush(&_iob[i]) == -1))
                retval = -1;
        }
    } else {
        if ((f->flag & _WRITE) == 0)
            return -1;
        _flushbuf(EOF, f);
        if (f->flag & _ERR)
            retval = -1;
    }
    return retval;
}

int fclose(FILE *f) {
    int fd;

    if (f == NULL)
        return -1;
    fd = f->fd;
    fflush(f);
    f->cnt = 0;
    f->ptr = NULL;
    if (f->base != NULL)
        free(f->base);
    f->base = NULL;
    f->flag = 0;
    f->fd = -1;
    return close(fd);
}

#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2

int fseek(FILE *f, long offset, int whence) {
    int result;

    if ((f->flag & _UNBUF) == 0 && f->base != NULL) {
        if (f->flag & _WRITE) {
            if (fflush(f))
                return EOF;
        } else if (f->flag & _READ) {
            if (whence == SEEK_CUR) {
                if(offset >= 0 && offset <= f->cnt){
                    f->cnt -= offset;
                    f->ptr += offset;
                    f->flag &= ~_EOF;
                    return 0;
                } else
                    offset -= f->cnt;
            }
            f->cnt = 0;
            f->ptr = f->base;
        }
    }
    result = (lseek(f->fd, offset, whence) < 0);
    if (result == 0)
        f->flag &= ~_EOF;
    return result;
}

int main(){
    int c;
    while((c = getchar()) != 'x'){
        putchar(c);
    }

	system("pause");
	return 0;
}

到了这里,关于C //练习 8-3 设计并编写函数_flushbuf、fflush和fclose。的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • python程序设计——练习4

    1.单词统计 — part one 【题目描述】 本题目要求编写程序统计一行字符中单词的个数。所谓“单词”是指连续不含空格的字符串,各单词之间用空格分隔,空格数可以是多个。 【输入描述】 输入给出一行字符。 【输出描述】 在一行中输出单词个数。 【输入样例1】 Let’s g

    2024年02月09日
    浏览(40)
  • 毕业设计商城小程序练习

    文章目录: 前言: 一:参考地址 二:其他 三:优势 四:技术工具 五:基本项目目录 六:主要页面 七:各个功能实现思路 八:补充 相关公主号:公众平台安全助手、微信公众平台、小程序商家助手 相关    web:微信公众平台、微信官方文档 前言: 代码下载:https://gi

    2024年02月16日
    浏览(40)
  • 团体程序设计天梯赛----pta 练习集

    这道超级简单的题目没有任何输入。 你只需要在一行中输出著名短句“Hello World!”就可以了。 解法 略 本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定17个“*”,要求按下列格式打印 解法 记录一下个数就好 给定一个 k 位整数 N,请编写程序统计每种不同的个

    2024年02月13日
    浏览(44)
  • 2021级Java程序设计课程练习题

    1-1 抽象类是不能实例化的。  T   1-2 JAVA抽象类中一定含有抽象方法。  F   答题时没有看到一定qaq,抽象类不一定包含抽象方法,但包含抽象方法的类一定是抽象类。 2-2 有如下程序代码, 程序运行的结果是( )。 D.false true 第一个竟然是false!!! 使用“==”比较两个字符

    2023年04月23日
    浏览(47)
  • Java程序设计2023-第三次上机练习

    这次的练习主要是一些类的高阶操作,像继承、接口和内部类这些,但其实还是挺简单的   目录 7-1 jmu-Java-03面向对象基础-04-形状-继承 前言 本题描述 思考 输入样例: 输出样例:  7-3 jmu-Java-04面向对象进阶-03-接口-自定义接口ArrayIntegerStack main方法说明 思考 输入样例 输出样例

    2024年02月05日
    浏览(47)
  • 团体程序设计天梯赛-练习集L2篇⑦

    🚀欢迎来到本文🚀 🍉个人简介:Hello大家好呀,我是陈童学,一个与你一样正在慢慢前行的普通人。 🏀个人主页:@陈童学哦`CSDN 💡所属专栏:PTA 🎁希望各位→点赞👍 + 收藏⭐️ + 留言📝 ​ ⛱️刷题的当下应是享受的!望与诸君共勉!🏄‍♂️ 下面是PTA的OJ平台 PTA的

    2024年02月11日
    浏览(88)
  • 【C++ 程序设计】实战:C++ 实践练习题(1~10)

    目录 01. 二维数组反对角线之和 02. 奇偶性  03. 指针与变量 04. 员工薪资  05. 整型值(%4d 进行格式化) 06. 求三个数中的最大值和最小值 07. 同一字母次数统计 08. 字符串回文判断 09. 闰年判断 10. 交换两个双精度数 【代码详解】 以上代码 计算的是 反对角线(从右上角到左下

    2024年02月14日
    浏览(39)
  • Java面向对象程序设计实验报告(实验五 接口的练习)

    ✨ 作者:命运之光  ✨ 专栏: Java面向对象程序设计实验报告 ​ 目录 ✨一、需求设计 ✨二、概要设计 ✨三、详细设计 ✨四、调试结果 ✨五、测试结果 ✨附录:源程序代码(带注释) demo5类 Instrument类 Piano类 play类 Student类 Teacher类 Violin类 work类  实验五 接口的练习 实验

    2024年02月06日
    浏览(44)
  • Java面向对象程序设计实验报告(实验二 面向对象基础练习)

     ✨ 作者: 命运之光  ✨  专栏:Java面向对象程序设计实验报告 目录 ✨一、需求设计 ✨二、概要设计 ✨三、详细设计 ✨四、调试结果 ✨五、测试结果 ✨附录:源程序代码(带注释) 测试类demo2 Address类 Employee类 实验二 面向对象基础练习 实验环境: Eclipse+JDK 实验目的:

    2024年02月06日
    浏览(72)
  • C++基础:文件操作函数fopen()和fclose()

    fopen函数用于打开一个文件,并返回一个文件指针,该指针可以用于后续的文件操作。其定义如下: 其中,filename 为要打开的文件的名称,可使用绝对地址或相对地址表示; mode 为文件打开模式,主要包括:   r :以只读方式打开文件。文件必须存在;   w :以只写方式打开文件。

    2024年01月20日
    浏览(26)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包