在 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;
}
我有一个文件在我的程序中作为标准输入传递。一个非常大的循环的每次迭代,一个方法 "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;
}