使用 fflush(stdin)

发布于 2024-09-04 06:58:05 字数 165 浏览 10 评论 0 原文

因此,在 Google 上快速搜索用于清除输入缓冲区的 fflush(stdin) 会发现许多网站警告不要使用它。然而,这正是我的计算机科学教授教授全班的方式。

使用 fflush(stdin) 有多糟糕?即使我的教授正在使用它并且它看起来效果完美,我真的应该放弃使用它吗?

So a quick Google search for fflush(stdin) for clearing the input buffer reveals numerous websites warning against using it. And yet that's exactly how my CS professor taught the class to do it.

How bad is using fflush(stdin)? Should I really abstain from using it, even though my professor is using it and it seems to work flawlessly?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

夜夜流光相皎洁 2024-09-11 06:58:05

简单:这是未定义的行为,因为 fflush 是在输出流上调用的。这是 C 标准的摘录:

int fflush(FILE *ostream);

ostream 指向输出流或
一个更新流,其中最
未输入最近操作,则
fflush 函数会导致任何未写入的
要传送的该流的数据
到要写入的主机环境
到文件;否则,该行为
未定义。

所以这不是“有多糟糕”的问题。 fflush(stdin) 根本不可移植,因此如果您希望代码在编译器之间可移植,则不应使用它。

Simple: this is undefined behavior, since fflush is meant to be called on an output stream. This is an excerpt from the C standard:

int fflush(FILE *ostream);

ostream points to an output stream or
an update stream in which the most
recent operation was not input, the
fflush function causes any unwritten
data for that stream to be delivered
to the host environment to be written
to the file; otherwise, the behavior
is undefined.

So it's not a question of "how bad" this is. fflush(stdin) is simply not portable, so you should not use it if you want your code to be portable between compilers.

一直在等你来 2024-09-11 06:58:05

将评论转换为答案。

TL;DR — 可移植代码不使用 fflush(stdin)

这个答案的其余部分解释了为什么可移植代码不使用 fflush(stdin)。人们很容易添加“可靠的代码不使用 fflush(stdin)”,这通常也是正确的。

标准 C 和 POSIX 将 fflush(stdin) 保留为未定义行为

POSIXfflush() 的 C 和 C++ 标准明确声明该行为未定义(因为 stdin 是输入流),但它们都没有阻止系统定义它。

ISO/IEC 9899:2011 — C11 标准 — 规定:

§7.21.5.2 fflush 函数< /h3>

¶2 如果 stream 指向未输入最近操作的输出流或更新流,则 fflush 函数会导致该流出现任何未写入的数据传送到主机环境写入文件;否则,行为未定义。

POSIX 主要遵循 C 标准,但它确实将此文本标记为 C 扩展。

[CX] ⌦ 对于打开读取的流,如果文件尚未位于 EOF,并且该文件能够查找,则底层打开文件描述的文件偏移量应设置为该文件的文件位置。流中,并且由 ungetc()ungetwc() 推回流中且随后未从流中读取的任何字符都应被丢弃(无需进一步更改文件)抵消)。 ⌫

请注意,终端无法进行搜索;管道或插座也不是。

Microsoft 将 fflush(stdin) 的行为定义为无操作

在 2015 年,Microsoft 和 Visual Studio 运行时用于在这样的输入流上定义 fflush() 的行为(但该链接在 2021 年会导致不同的文本 - 并且甚至“2015”版本中的文本也不同):

如果流打开以供输入,fflush 会清除缓冲区的内容。

MM注释

Cygwin 是一个相当常见的平台示例,在该平台上 fflush(stdin) 不会清除输入。

这就是为什么我的评论的这个答案版本指出“Microsoft和Visual Studio运行时” - 如果您使用非 Microsoft C 运行时库,您看到的行为取决于该库。

Weather Vane 在对另一个问题的评论中向我指出,在 2021 年 6 月之前的某个时间,微软更改了其fflush 的说明() 与 2015 年编写此答案时最初指定的内容相比。现在显示:

如果流以读取模式打开,或者流没有缓冲区,则对 fflush 的调用无效,并且保留任何缓冲区。对 fflush 的调用会消除之前对流的 ungetc 调用的效果。

警告Lector:最好不要依赖fflush(stdin) 在任何平台上。

Linux 文档和实践似乎相互矛盾

令人惊讶的是,Linux 名义上记录了 < code>fflush(stdin) 也是如此,甚至以相同的方式定义它(奇迹中的奇迹)。这句话是2015年的。

对于输入流,fflush() 会丢弃从底层文件中获取但尚未被应用程序使用的任何缓冲数据。

2021 年,报价更改为:

对于输入流,fflush() 会丢弃从底层文件中获取但尚未被应用程序使用的所有缓冲数据。流的打开状态不受影响。

另一个来源 fflush(3)< Linux 上的 /a> 表示同意(给予或保留段落分隔符):

对于与可查找文件关联的输入流(例如,磁盘文件,但不是管道或终端),fflush() 丢弃已从底层文件中获取但尚未被读取的任何缓冲数据。由应用程序使用。

这些都没有明确解决 POSIX 规范中有关 ungetc() 的要点。

2021 年,zwol 评论 Linux 文档已得到改进。
在我看来,还有改进的空间。

2015 年,我对 Linux 文档说 fflush(stdin) 可以工作感到有点困惑和惊讶。
尽管有这样的建议,但它通常在 Linux 上不起作用。我刚刚查看了 Ubuntu 14.04 LTS 的文档;它说了上面引用的内容,但从经验来看,它不起作用 - 至少当输入流是不可搜索的设备(例如终端)时。

demo-fflush.c

#include <stdio.h>

int main(void)
{
    int c;
    if ((c = getchar()) != EOF)
    {
        printf("Got %c; enter some new data\n", c);
        fflush(stdin);
    }
    if ((c = getchar()) != EOF)
        printf("Got %c\n", c);

    return 0;
}

示例输出

$ ./demo-fflush
Alliteration
Got A; enter some new data
Got l
$

此输出是在 Ubuntu 14.04 LTS 和 Mac OS X 10.11.2 上获得的。据我了解,这与Linux手册的内容相矛盾。如果 fflush(stdin) 操作有效,我将必须键入新行文本才能获取第二个 getchar() 读取的信息。

鉴于 POSIX 标准的规定,也许需要更好的演示,并且应该澄清 Linux 文档。

demo-fflush2.c

#include <stdio.h>

int main(void)
{
    int c;
    if ((c = getchar()) != EOF)
    {
        printf("Got %c\n", c);
        ungetc('B', stdin);
        ungetc('Z', stdin);
        if ((c = getchar()) == EOF)
        {
            fprintf(stderr, "Huh?!\n");
            return 1;
        }
        printf("Got %c after ungetc()\n", c);
        fflush(stdin);
    }
    if ((c = getchar()) != EOF)
        printf("Got %c\n", c);

    return 0;
}

示例输出

请注意,/etc/passwd 是一个可查找文件。在 Ubuntu 上,第一行如下所示:

root:x:0:0:root:/root:/bin/bash

在 Mac OS X 上,前 4 行如下所示:

##
# User Database
# 
# Note that this file is consulted directly only when the system is running

换句话说,Mac OS X /etc/passwd 文件的顶部有注释。非注释行符合正常布局,因此 root 条目为:

root:*:0:0:System Administrator:/var/root:/bin/sh

Ubuntu 14.04 LTS:

$ ./demo-fflush2 < /etc/passwd
Got r
Got Z after ungetc()
Got o
$ ./demo-fflush2
Allotrope
Got A
Got Z after ungetc()
Got B
$

Mac OS X 10.11.2:

$ ./demo-fflush2 < /etc/passwd
Got #
Got Z after ungetc()
Got B
$

Mac OS X 行为忽略(或至少看起来忽略) fflush(stdin)(因此在这个问题上不遵循 POSIX)。 Linux 行为与记录的 POSIX 行为相对应,但 POSIX 规范在其表述上要谨慎得多 — 它指定了能够查找的文件,但终端当然不支持查找。它的用处也远不如 Microsoft 规范。

摘要

Microsoft 记录了 fflush(stdin) 的行为,但该行为在 2015 年到 2021 年间发生了变化。显然,它的工作原理与 Windows 平台上记录的一样,使用本机 Windows 编译器和 C 运行时支持库。

尽管文档与此相反,当标准输入是终端时,它在 Linux 上不起作用,但它似乎遵循措辞更为仔细的 POSIX 规范。根据 C 标准,fflush(stdin) 的行为是未定义的。 POSIX 添加了限定符“除非输入文件是可查找的”,而终端则不是。该行为与微软的不一样。

因此,可移植代码不使用fflush(stdin)。与 Microsoft 平台相关的代码可以使用它并且它可以按预期工作,但要注意可移植性问题。

丢弃来自文件描述符的未读终端输入的 POSIX 方法 丢弃

来自终端文件描述符的未读信息的 POSIX 标准方法(与 stdin 等文件流相反)在 如何从a中刷新未读数据Unix 系统上的 tty 输入队列。然而,这是在标准 I/O 库级别以下运行的。

Converting comments into an answer.

TL;DR — Portable code doesn't use fflush(stdin)

The rest of this answer explains why portable code does not use fflush(stdin). It is tempting to add "reliable code doesn't use fflush(stdin)", which is also generally true.

Standard C and POSIX leave fflush(stdin) as undefined behaviour

The POSIX, C and C++ standards for fflush() explicitly state that the behaviour is undefined (because stdin is an input stream), but none of them prevent a system from defining it.

ISO/IEC 9899:2011 — the C11 Standard — says:

§7.21.5.2 The fflush function

¶2 If stream points to an output stream or an update stream in which the most recent operation was not input, the fflush function causes any unwritten data for that stream to be delivered to the host environment to be written to the file; otherwise, the behavior is undefined.

POSIX mostly defers to the C standard but it does mark this text as a C extension.

[CX] ⌦ For a stream open for reading, if the file is not already at EOF, and the file is one capable of seeking, the file offset of the underlying open file description shall be set to the file position of the stream, and any characters pushed back onto the stream by ungetc() or ungetwc() that have not subsequently been read from the stream shall be discarded (without further changing the file offset). ⌫

Note that terminals are not capable of seeking; neither are pipes or sockets.

Microsoft defines the behaviour of fflush(stdin) as a no-op

In 2015, Microsoft and the Visual Studio runtime used to define the behaviour of fflush() on an input stream like this (but the link leads to different text in 2021 — and even the text in the '2015' version is different):

If the stream is open for input, fflush clears the contents of the buffer.

M.M notes:

Cygwin is an example of a fairly common platform on which fflush(stdin) does not clear the input.

This is why this answer version of my comment notes 'Microsoft and the Visual Studio runtime' — if you use a non-Microsoft C runtime library, the behaviour you see depends on that library.

Weather Vane pointed out to me in a comment to another question that, at some time before June 2021, Microsoft changed its description of fflush() compared with what was originally specified when this answer was written in 2015. It now says:

If the stream was opened in read mode, or if the stream has no buffer, the call to fflush has no effect, and any buffer is retained. A call to fflush negates the effect of any prior call to ungetc for the stream.

Caveat Lector: it is probably best not to rely on fflush(stdin) on any platform.

Linux documentation and practice seem to contradict each other

Surprisingly, Linux nominally documents the behaviour of fflush(stdin) too, and even defines it the same way (miracle of miracles). This quote is from 2015.

For input streams, fflush() discards any buffered data that has been fetched from the underlying file, but has not been consumed by the application.

In 2021, the quote changes to:

For input streams, fflush() discards any buffered data that has been fetched from the underlying file, but has not been consumed by the application. The open status of the stream is unaffected.

And another source for fflush(3) on Linux agrees (give or take paragraph breaks):

For input streams associated with seekable files (e.g., disk files, but not pipes or terminals), fflush() discards any buffered data that has been fetched from the underlying file, but has not been consumed by the application.

Neither of these explicitly addresses the points made by the POSIX specification about ungetc().

In 2021, zwol commented that the Linux documentation has been improved.
It seems to me that there is still room for improvement.

In 2015, I was a bit puzzled and surprised at the Linux documentation saying that fflush(stdin) will work.
Despite that suggestion, it most usually does not work on Linux. I just checked the documentation on Ubuntu 14.04 LTS; it says what is quoted above, but empirically, it does not work — at least when the input stream is a non-seekable device such as a terminal.

demo-fflush.c

#include <stdio.h>

int main(void)
{
    int c;
    if ((c = getchar()) != EOF)
    {
        printf("Got %c; enter some new data\n", c);
        fflush(stdin);
    }
    if ((c = getchar()) != EOF)
        printf("Got %c\n", c);

    return 0;
}

Example output

$ ./demo-fflush
Alliteration
Got A; enter some new data
Got l
$

This output was obtained on both Ubuntu 14.04 LTS and Mac OS X 10.11.2. To my understanding, it contradicts what the Linux manual says. If the fflush(stdin) operation worked, I would have to type a new line of text to get information for the second getchar() to read.

Given what the POSIX standard says, maybe a better demonstration is needed, and the Linux documentation should be clarified.

demo-fflush2.c

#include <stdio.h>

int main(void)
{
    int c;
    if ((c = getchar()) != EOF)
    {
        printf("Got %c\n", c);
        ungetc('B', stdin);
        ungetc('Z', stdin);
        if ((c = getchar()) == EOF)
        {
            fprintf(stderr, "Huh?!\n");
            return 1;
        }
        printf("Got %c after ungetc()\n", c);
        fflush(stdin);
    }
    if ((c = getchar()) != EOF)
        printf("Got %c\n", c);

    return 0;
}

Example output

Note that /etc/passwd is a seekable file. On Ubuntu, the first line looks like:

root:x:0:0:root:/root:/bin/bash

On Mac OS X, the first 4 lines look like:

##
# User Database
# 
# Note that this file is consulted directly only when the system is running

In other words, there is commentary at the top of the Mac OS X /etc/passwd file. The non-comment lines conform to the normal layout, so the root entry is:

root:*:0:0:System Administrator:/var/root:/bin/sh

Ubuntu 14.04 LTS:

$ ./demo-fflush2 < /etc/passwd
Got r
Got Z after ungetc()
Got o
$ ./demo-fflush2
Allotrope
Got A
Got Z after ungetc()
Got B
$

Mac OS X 10.11.2:

$ ./demo-fflush2 < /etc/passwd
Got #
Got Z after ungetc()
Got B
$

The Mac OS X behaviour ignores (or at least seems to ignore) the fflush(stdin) (thus not following POSIX on this issue). The Linux behaviour corresponds to the documented POSIX behaviour, but the POSIX specification is far more careful in what it says — it specifies a file capable of seeking, but terminals, of course, do not support seeking. It is also much less useful than the Microsoft specification.

Summary

Microsoft documents the behaviour of fflush(stdin), but that behaviour has changed between 2015 and 2021. Apparently, it works as documented on the Windows platform, using the native Windows compiler and C runtime support libraries.

Despite documentation to the contrary, it does not work on Linux when the standard input is a terminal, but it seems to follow the POSIX specification which is far more carefully worded. According to the C standard, the behaviour of fflush(stdin) is undefined. POSIX adds the qualifier 'unless the input file is seekable', which a terminal is not. The behaviour is not the same as Microsoft's.

Consequently, portable code does not use fflush(stdin). Code that is tied to Microsoft's platform may use it and it may work as expected, but beware of the portability issues.

POSIX way to discard unread terminal input from a file descriptor

The POSIX standard way to discard unread information from a terminal file descriptor (as opposed to a file stream like stdin) is illustrated at How can I flush unread data from a tty input queue on a Unix system. However, that is operating below the standard I/O library level.

醉南桥 2024-09-11 06:58:05

根据标准,fflush 只能与输出缓冲区一起使用,显然 stdin 不是其中之一。但是,一些标准 C 库提供了 fflush( stdin) 作为扩展。在那种情况下你可以使用它,但它会影响可移植性,因此你将不再能够使用地球上任何符合标准的标准C库并期望得到相同的结果。

According to the standard, fflush can only be used with output buffers, and obviously stdin isn't one. However, some standard C libraries provide the use of fflush(stdin) as an extension. In that case you can use it, but it will affect portability, so you will no longer be able to use any standards-compliant standard C library on earth and expect the same results.

假情假意假温柔 2024-09-11 06:58:05

我相信您永远不应该调用 fflush(stdin) ,原因很简单,您甚至不应该发现有必要首先尝试刷新输入。实际上,您可能认为必须刷新输入的原因只有一个,那就是:为了克服 scanf 卡住的一些错误输入。

例如,您可能有一个程序正在使用 scanf("%d", &n) 循环读取整数。很快您就会发现,当用户第一次输入非数字字符(例如 'x')时,程序进入无限循环

面对这种情况,我相信您基本上有三种选择:

  1. 以某种方式刷新输入(如果不是使用 fflush(stdin) ,然后在循环中调用 getchar 来刷新输入)读取字符直到 \n,正如通常建议的那样)。
  2. 告诉用户在需要数字时不要键入非数字字符。
  3. 使用 scanf 以外的其他内容读取输入

现在,如果您是初学者,scanf似乎是读取输入的最简单方法,因此选择 #3 看起来既可怕又困难。但#2 似乎是一个真正的逃避,因为每个人都知道用户不友好的计算机程序是一个问题,所以最好做得更好。因此,太多的新手程序员陷入了困境,觉得自己别无选择,只能做第一件事。他们或多或少必须使用 scanf 进行输入,这意味着它将卡在错误的输入上,这意味着他们必须找到一种方法来刷新错误的输入,这意味着他们非常受诱惑使用fflush(stdin)。

我想鼓励所有初级 C 程序员做出不同的权衡:

  1. 在 C 编程职业生涯的最初阶段,在您习惯使用 scanf 以外的任何内容之前,只是不用担心错误的输入。真的。继续使用上面的逃避#2。这样想:你是一个初学者,有很多事情你还不知道如何做,而你还不知道如何做的事情之一就是:优雅地处理意外的输入。< /p>

  2. 尽快了解如何使用 scanf 以外的函数进行输入。那时,您可以开始优雅地处理错误输入,并且您将拥有更多、更好的技术可用,而根本不需要尝试“刷新错误输入”。

或者,换句话说,仍然坚持使用 scanf 的初学者应该随意使用逃避 #2,当他们准备好时,他们应该从那里升级到技术 #3,并且没有人应该这样做使用技术 #1 来尝试刷新输入——当然不是使用 fflush(stdin) 。

I believe that you should never call fflush(stdin), and for the simple reason that you should never even find it necessary to try to flush input in the first place. Realistically, there is only one reason you might think you had to flush input, and that is: to get past some bad input that scanf is stuck on.

For example, you might have a program that is sitting in a loop reading integers using scanf("%d", &n). Soon enough you'll discover that the first time the user types a non-digit character like 'x', the program goes into an infinite loop.

When faced with this situation, I believe you basically have three choices:

  1. Flush the input somehow (if not by using fflush(stdin), then by calling getchar in a loop to read characters until \n, as is often recommended).
  2. Tell the user not to type non-digit characters when digits are expected.
  3. Use something other than scanf to read input.

Now, if you're a beginner, scanf seems like the easiest way to read input, and so choice #3 looks scary and difficult. But #2 seems like a real cop-out, because everyone knows that user-unfriendly computer programs are a problem, so it'd be nice to do better. So all too many beginning programmers get painted into a corner, feeling that they have no choice but to do #1. They more or less have to do input using scanf, meaning that it will get stuck on bad input, meaning that they have to figure out a way to flush the bad input, meaning that they're sorely tempted to use fflush(stdin).

I would like to encourage all beginning C programmers out there to make a different set of tradeoffs:

  1. During the earliest stages of your C programming career, before you're comfortable using anything other than scanf, just don't worry about bad input. Really. Go ahead and use cop-out #2 above. Think about it like this: You're a beginner, there are lots of things you don't know how to do yet, and one of the things you don't know how to do yet is: deal gracefully with unexpected input.

  2. As soon as you can, learn how to do input using functions other than scanf. At that point, you can start dealing gracefully with bad input, and you'll have many more, much better techniques available to you, that won't require trying to "flush the bad input" at all.

Or, in other words, beginners who are still stuck using scanf should feel free to use cop-out #2, and when they're ready they should graduate from there to technique #3, and nobody should be using technique #1 to try to flush input at all -- and certainly not with fflush(stdin).

甜点 2024-09-11 06:58:05

使用 fflush(stdin) 刷新输入有点像探水 使用形状像字母“S”的棍子。

帮助人们以某种​​“更好”的方式刷新输入有点像冲向 S 杆探光器并说“不,不,你做错了,
你需要使用 Y 形棒!”。

换句话说,真正的问题不是 fflush(stdin) 不起作用。调用 fflush(stdin) 是潜在问题的症状。为什么您必须“刷新”输入?这就是您的问题。

通常,该潜在问题是您正在使用 scanf<。 /code> 的许多无用模式之一会意外地在输入中留下换行符或其他“不需要的”文本,因此,最好的长期解决方案是 学习如何使用比 scanf 更好的技术进行输入,这样您就不会根本不必处理其未处理的输入和其他特性。

Using fflush(stdin) to flush input is kind of like dowsing for water using a stick shaped like the letter "S".

And helping people to flush input in some "better" way is kind of like rushing up to an S-stick dowser and saying "No, no, you're doing it wrong,
you need to use a Y-shaped stick!".

In other words, the real problem isn't that fflush(stdin) doesn't work. Calling fflush(stdin) is a symptom of an underlying problem. Why are you having to "flush" input at all? That's your problem.

And, usually, that underlying problem is that you're using scanf, in one of its many unhelpful modes that unexpectedly leaves newlines or other "unwanted" text on the input. The best long-term solution, therefore, is to learn how to do input using better techniques than scanf, so that you don't have to deal with its unhandled input and other idiosyncrasies at all.

明天过后 2024-09-11 06:58:05

现有的答案都没有指出问题的关键方面。

如果您发现自己想要“清除输入缓冲区”,那么您可能正在编写一个命令行交互式程序,更准确的说法是您想要丢弃当前输入中您尚未读取的字符。

这不是 fflush(stdin) 的作用。支持在输入流上使用 fflush 的 C 库将其记录为什么都不做,或者丢弃从底层文件读取的缓冲数据,但未传递给应用程序。这很容易比当前行的其余部分输入更多更少。在很多情况下,它可能会意外地工作,因为终端驱动程序(在默认模式下)一次一行地向命令行交互程序提供输入。然而,当您尝试从磁盘上的实际文件向程序提供输入时(可能是为了自动化测试),内核和 C 库将切换到以大“块”(通常为 4 到 8 kB)缓冲数据,而不会产生任何影响。与行边界的关系,您会想知道为什么您的程序要处理文件的第一行,然后跳过几十行并在下面一些明显随机的行的中间中进行拾取。或者,如果您决定在手写的很长的行上测试程序,那么终端驱动程序将无法立即为程序提供整行和 fflush(stdin ) 不会跳过所有内容。

那么你应该做什么呢?我更喜欢的方法是,如果您一次处理一行输入,则一次读取整行。 C 库有专门用于此目的的函数:fgets(在 C90 中,因此完全可移植,但仍然使您可以分块处理很长的行)和 getline(POSIX 特定的,但会为您管理一个 malloc 缓冲区,这样您就可以一次处理长行,无论它们有多长)。通常存在从直接从 stdin 处理“当前行”的代码到处理包含“当前行”的字符串的代码的直接转换。

None of the existing answers point out a key aspect of the issue.

If you find yourself wanting to "clear the input buffer", you're probably writing a command-line interactive program, and it would be more accurate to say that what you want is to discard characters from the current line of input that you haven't already read.

This is not what fflush(stdin) does. The C libraries that support using fflush on an input stream, document it as either doing nothing, or as discarding buffered data that has been read from the underlying file but not passed to the application. That can easily be either more or less input than the rest of the current line. It probably does work by accident in a lot of cases, because the terminal driver (in its default mode) supplies input to a command-line interactive program one line at a time. However, the moment you try to feed input to your program from an actual file on disk (perhaps for automated testing), the kernel and C library will switch over to buffering data in large "blocks" (often 4 to 8 kB) with no relationship to line boundaries, and you'll be wondering why your program is processing the first line of the file and then skipping several dozen lines and picking up in the middle of some apparently random line below. Or, if you decide to test your program on a very long line typed by hand, then the terminal driver won't be able to give the program the whole line at once and fflush(stdin) won't skip all of it.

So what should you do instead? The approach that I prefer is, if you're processing input one line at a time, then read an entire line all at once. The C library has functions specifically for this: fgets (in C90, so fully portable, but does still make you process very long lines in chunks) and getline (POSIX-specific, but will manage a malloced buffer for you so you can process long lines all at once no matter how long they get). There's usually a direct translation from code that processes "the current line" directly from stdin to code that processes a string containing "the current line".

生生不灭 2024-09-11 06:58:05

引用自 POSIX

对于打开以供读取的流,如果文件尚未位于 EOF,并且文件是一个
能够查找,应设置底层打开文件描述的文件偏移量
到流的文件位置,以及通过以下方式推回到流上的任何字符
随后未从流中读取的 ungetc() 或 ungewc() 应被释放
梳理(无需进一步更改文件偏移量)。

请注意,终端无法进行搜索。

Quote from POSIX:

For a stream open for reading, if the file is not already at EOF, and the file is one
capable of seeking, the file offset of the underlying open file description shall be set
to the file position of the stream, and any characters pushed back onto the stream by
ungetc() or ungetwc() that have not subsequently been read from the stream shall be dis-
carded (without further changing the file offset).

Note that terminal is not capable of seeking.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文