在 C 中,是否可以在不移动缓冲区指针的情况下从 getchar 的当前缓冲区位置读取一个 char?

In C, is it possible to read a char from getchar's current buffer position without moving the buffer's pointer?

我有一个文件在我的程序中作为标准输入传递。一个非常大的循环的每次迭代,一个方法 "get_next" 调用 getchar,并获取标准输入中的下一个字符并将其分配给名为 nchar 的变量。

问题是,我有一个实例,我必须查看当前 nchar 之后的 char,而不更改对 get_next 的下一次调用所做的事情。意思是,我必须在不更改缓冲区状态的情况下调用 getchar()。

有办法吗?是否有像 "getcharStatic" 这样的方法 returns 下一个字符而不更改缓冲区,就像堆栈的 peek 与 pop 一样?

或者,有没有一种方法可以使用 getchar 正常读取 char,然后将 char 插入我从中取出的位置,从而人为地保存缓冲区的状态?

我用谷歌搜索了一会儿,我认为这个问题涉及到过于模糊的术语和标签。感谢您的帮助!

您可以使用 ungetc() 将字符推回标准输入。这是来自 doc 的简介:

int ungetc( int ch, FILE *stream ); 

If ch does not equal EOF, pushes the character ch (reinterpreted as unsigned char) into the input buffer associated with the stream stream in such a manner that subsequent read operation from stream will retrieve that character.

你可以使用ungetc(),可能是这样的:

int fpeekc(FILE *fp)
{
    int c = getc(fp);
    if (c != EOF)
        ungetc(c, fp);
    return c;
}

仔细阅读 POSIX 规范表明您可以使用 EOF 调用 ungetc() 并且该调用将被忽略,因此并非 100% 有必要在 fpeekc() 函数,但它确实使 ungetc() 失败并且 return EOF。如果你喜欢生活——危险的或紧凑的;选择你的选择——你可以使用:

int fpeekc(FILE *fp)
{
    return ungetc(getc(fp), fp);
}

如果需要,您可以将其设为内联函数。如果你在 POSIX 并且需要线程安全,你可以使用:

int fpeekc(FILE *fp)
{
    flockfile(fp);
    int c = getc_unlocked(fp);  // Legitimate because of flockfile(); getc(fp) works too
    if (c != EOF)
    {
        // ungetc_unlocked() is not defined by POSIX but is available on
        // some but not all POSIX-like systems.  See comments below.
        ungetc(c, fp);
    }
    funlockfile(fp);
    return c;
}

这可以防止另一个线程在您处理流时干扰流。另请参阅下面评论中与 Nominal Animal 的讨论。

你可以使用:

static inline int peekc(void) { return fpeekc(stdin); }

如果你想为标准输入做。

我想你想要 int ungetc(int char, FILE *stream)。 你可以有一个方法:

char fgetputbackc(file *f){
    int c = fgetc(f);
    ungetc(c, f);
    return c;
}