我目前正在研究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};
如您所见,这是像堆栈一样实现的(最后在->中先出)。这让我心烦。在本例中:
ungetch('a');
ungetch('b');
ungetch('c');getch()将在第一个函数调用时返回'c‘。第二个函数调用的'b‘和第三个函数调用的'a’。我喜欢在开始时获得第一个'ungetch()'-ed char,在最后得到最后一个'ungetch'-ed char的想法。
我就是这样做的:
#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进程成功的信息,并将其提供给调用方。
发布于 2015-11-10 23:52:45
reorder_buf()效率低得可怕,如果您将缓冲区用作循环列表,则没有必要。你想要的是一个环形缓冲器。
/* 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。
发布于 2015-11-11 00:33:19
您的ungetch在出错时有非常奇怪的行为。
我不太确定它比On Error Resume Next更好还是更糟,但肯定是在同一个类中。
要么自己处理它,这意味着向stderr报告错误并中止程序,要么向调用方报告它(有关方法请参阅ungetc上的文档)。
目前,您打印了一条错误消息(它可能会在输出中丢失,而且不管怎么说,有一个人在积极和专注地监视事物),但随后愉快地继续处理数据丢失问题,而不通知调用者。
https://codereview.stackexchange.com/questions/110400
复制相似问题