首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >FIFO getch/ungetch函数

FIFO getch/ungetch函数
EN

Code Review用户
提问于 2015-11-10 20:58:06
回答 2查看 262关注 0票数 3

我目前正在研究K&R,只读到有关实现getch()ungetch()的文章。

在K&R中,这些功能的实现方式如下:

#包括 #定义BUFSIZE 100 char BUFSIZE;用于ungetch */ int bufp =0的/*缓冲区;/*在buf */ int (Void) /*中的下一个自由位置得到一个(可能是向后推的)字符*/ { free (bufp > 0)?buf--bufp:getchar();} void (Int c) /*将字符推回输入*/ { if (bufp >= BUFSIZE) printf("ungetch:太多字符\n“);否则bufbufp++ =c};

如您所见,这是像堆栈一样实现的(最后在->中先出)。这让我心烦。在本例中:

代码语言:javascript
复制
ungetch('a');
ungetch('b');
ungetch('c');

getch()将在第一个函数调用时返回'c‘。第二个函数调用的'b‘和第三个函数调用的'a’。我喜欢在开始时获得第一个'ungetch()'-ed char,在最后得到最后一个'ungetch'-ed char的想法。

我就是这样做的:

代码语言:javascript
复制
#include <stdio.h>

#define BUFSIZE 10
static int reorder_buf(void);

char buf[BUFSIZE];
int bufrp = 0;    //buffer read position
int bufwp = 0;    //buffer write position

int getch(void)
{
    if (bufrp < bufwp)
        return buf[bufrp++];
    else {
        if(bufwp != 0)
            bufwp = bufrp = 0;

        return getchar();
    }
}

void ungetch(int c)
{
    if (bufwp < BUFSIZE)
        buf[bufwp++]=c;
    else
    {
        if (reorder_buf() != 0)     //successful reorder
        {
            buf[bufwp++]=c;
        } else                      //full buffer
        {
            printf("Failed to ungetch(%c).\n", c);
        }
    }
}

/**
 * Tries to move buffer content to the start of the buffer.
 *
 * @return 1 on successful reorder, 0 otherwise
 */
static int reorder_buf(void)
{
    if (bufrp > 0)
    {
        int i;
        for(i = 0; bufrp < bufwp; bufrp++, i++)
             buf[i] = buf[bufrp];

        bufrp = 0;
        bufwp = i;
        return 1;
     } else
     {
         return 0;
     }
}

我还想将ungetch()中的错误消息替换为返回int,其中包括如果unget进程成功的信息,并将其提供给调用方。

EN

回答 2

Code Review用户

回答已采纳

发布于 2015-11-10 23:52:45

reorder_buf()效率低得可怕,如果您将缓冲区用作循环列表,则没有必要。你想要的是一个环形缓冲器。

代码语言:javascript
复制
/* Store up to 10 characters */
#define BUFSIZE 11

char buf[BUFSIZE];
int qhead = 0, qtail = 0;

int getch(void) {
    if (qhead != qtail) {
        int c = buf[qhead];
        qhead = (qhead + 1) % BUFSIZE;
        return c;
    } else {
        return getchar();
    }
}

void ungetch(int c) {
    if ((qtail + 1) % BUFSIZE == qhead) {
        fprintf(stderr, "Buffer full, dropped %c.\n", c);
    } else {
        buf[qtail] = c;
        qtail = (qtail + 1) % BUFSIZE;
    }
}

错误应该转到stderr而不是stdout

票数 2
EN

Code Review用户

发布于 2015-11-11 00:33:19

您的ungetch在出错时有非常奇怪的行为。

我不太确定它比On Error Resume Next更好还是更糟,但肯定是在同一个类中。

要么自己处理它,这意味着向stderr报告错误并中止程序,要么向调用方报告它(有关方法请参阅ungetc上的文档)。

目前,您打印了一条错误消息(它可能会在输出中丢失,而且不管怎么说,有一个人在积极和专注地监视事物),但随后愉快地继续处理数据丢失问题,而不通知调用者。

票数 0
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/110400

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档