fflush(stdin) 和 flushstdin() 之间的区别
Difference between fflush(stdin) and flushstdin()
使用有什么区别fflush(stdin)
flushstdin()
?我知道的唯一区别是我需要在使用 flushstdin()
之前写那些无效的东西,但我不知道为什么。
void flushstdin()
{
int c;
while((c = getchar()) != '\n' && c != EOF);
}
int main () {
float a, b, c;
float s=0, ar1=0, ar2=0;
printf("Inform value of side A");
while(scanf("%f",&a) != 1 || a <= 0){
printf("Invalid value.\n");
flushstdin();
}
}
和
int main(){
float a,b,c,s=0;
printf("Inform value of side A.");
while(scanf("%f",&a) != 1 || a<=0){
printf("Invalid value.\n");
fflush(stdin);
}
}
我是初学者!哪个代码最好?或者它们是相等的?
区别在于 flushstdin
是用户定义的,并且是标准 C 中刷新 stdin
.
的唯一方法
fflush
是标准库函数。 fflush(stdin);
将调用未定义的行为。
fflush
is defined only for output streams. Since its definition of "flush" is to complete the writing of buffered characters (not to discard them), discarding unread input would not be an analogous meaning for fflush
on input streams.
There is no standard way to discard unread characters from a stdio input stream. Some vendors do implement fflush
so that fflush(stdin)
discards unread characters, although portable programs cannot depend on this. (Some versions of the stdio
library implement fpurge
or fabort
calls which do the same thing, but these aren't standard, either.) Note, too, that flushing stdio
input buffers is not necessarily sufficient: unread characters can also accumulate in other, OS-level input buffers. If you're trying to actively discard input (perhaps in anticipation of issuing an unexpected prompt to confirm a destructive action, for which an accidentally-typed "y" could be disastrous), you'll have to use a system-specific technique to detect the presence of typed-ahead input; see questions 19.1 and 19.2. Keep in mind that users can become frustrated if you discard input that happened to be typed too quickly.
他们完全不同。他们都可以"flush"输入,但输入的意义不同。
fflush
是一个标准的 C 函数。它在 stdin
等输入流上的行为是 undefined —— 这意味着 C 标准没有定义它的行为。
一些系统确实定义了 fflush
在输入流上的行为。例如 Linux:
For input streams, fflush()
discards any buffered data that has been
fetched from the underlying file, but has not been consumed by the
application.
如果您的程序在基于 Linux 的系统或其他系统上运行,您可以依赖 fflush(stdin)
来按照此描述运行 记录相同的行为。您的程序的行为将不可移植;在其他系统上,它可能会以任意糟糕的方式运行。 (很可能如果 fflush(stdin)
不起作用,除了 return 错误指示外,它什么都不做,但这不能保证。)
您自己的 flushstdin
函数与 fflush(stdin)
的 Linux 行为不同。它读取并丢弃所有输入函数,直到第一个换行符或直到 EOF
(由文件结束或错误触发)。无论该输入是否被缓冲,它都会执行此操作。
例如,假设您键入字符 hello
(没有换行符),然后您的程序调用 fflush(stdin)
、,然后 您输入换行符.
fflush(stdin)
,鉴于 Linux 记录的行为,将立即丢弃 hello
和 return,留下换行符以供稍后调用读取。它 "flushes" stdin
在某种意义上它会丢弃所有待处理的输入,无论它是什么。
您的 flushstdin()
函数将读取并丢弃 hello
,然后等待您键入 Enter(或 Ctrl-D), 然后阅读并丢弃它。它读取并丢弃直到换行符或 EOF 的所有输入,无论它在调用时是否处于挂起状态。
同样,fflush(stdin)
的行为未由 C 标准定义,因此使用它会使您的程序不可移植(并且您的编译器不一定会警告您)。
顺便说一句,"that void stuff"是flushstdin
函数的定义。 fflush
不需要它,因为这是已经为您定义的标准 C 库函数。
两个版本都有问题。
正如已经广泛记录的那样,fflush(stdin)
根据 C 标准具有未定义的行为。使用 flushstdin()
函数的替代方案也好不到哪儿去。我建议一次读取一行标准输入并使用 sscanf()
解析它,所有这些都在您可以根据需要使用的实用函数中:
int readfloat(const char *prompt, float *val) {
char buf[128];
for (;;) {
if (prompt)
fputs(prompt, stdout);
if (!fgets(buf, sizeof(buf), stdin)) {
printf("Premature end of file\n");
return 1;
}
if (sscanf(buf, "%f", val) == 1 && *val > 0)
return 0;
printf("Invalid value.\n");
}
}
int main(void) {
float a, b, c, s = 0;
if (readfloat("Enter value of side A: ", &a))
return 1;
...
}
使用有什么区别fflush(stdin)
flushstdin()
?我知道的唯一区别是我需要在使用 flushstdin()
之前写那些无效的东西,但我不知道为什么。
void flushstdin()
{
int c;
while((c = getchar()) != '\n' && c != EOF);
}
int main () {
float a, b, c;
float s=0, ar1=0, ar2=0;
printf("Inform value of side A");
while(scanf("%f",&a) != 1 || a <= 0){
printf("Invalid value.\n");
flushstdin();
}
}
和
int main(){
float a,b,c,s=0;
printf("Inform value of side A.");
while(scanf("%f",&a) != 1 || a<=0){
printf("Invalid value.\n");
fflush(stdin);
}
}
我是初学者!哪个代码最好?或者它们是相等的?
区别在于 flushstdin
是用户定义的,并且是标准 C 中刷新 stdin
.
的唯一方法
fflush
是标准库函数。 fflush(stdin);
将调用未定义的行为。
fflush
is defined only for output streams. Since its definition of "flush" is to complete the writing of buffered characters (not to discard them), discarding unread input would not be an analogous meaning forfflush
on input streams.
There is no standard way to discard unread characters from a stdio input stream. Some vendors do implement
fflush
so thatfflush(stdin)
discards unread characters, although portable programs cannot depend on this. (Some versions of thestdio
library implementfpurge
orfabort
calls which do the same thing, but these aren't standard, either.) Note, too, that flushingstdio
input buffers is not necessarily sufficient: unread characters can also accumulate in other, OS-level input buffers. If you're trying to actively discard input (perhaps in anticipation of issuing an unexpected prompt to confirm a destructive action, for which an accidentally-typed "y" could be disastrous), you'll have to use a system-specific technique to detect the presence of typed-ahead input; see questions 19.1 and 19.2. Keep in mind that users can become frustrated if you discard input that happened to be typed too quickly.
他们完全不同。他们都可以"flush"输入,但输入的意义不同。
fflush
是一个标准的 C 函数。它在 stdin
等输入流上的行为是 undefined —— 这意味着 C 标准没有定义它的行为。
一些系统确实定义了 fflush
在输入流上的行为。例如 Linux:
For input streams,
fflush()
discards any buffered data that has been fetched from the underlying file, but has not been consumed by the application.
如果您的程序在基于 Linux 的系统或其他系统上运行,您可以依赖 fflush(stdin)
来按照此描述运行 记录相同的行为。您的程序的行为将不可移植;在其他系统上,它可能会以任意糟糕的方式运行。 (很可能如果 fflush(stdin)
不起作用,除了 return 错误指示外,它什么都不做,但这不能保证。)
您自己的 flushstdin
函数与 fflush(stdin)
的 Linux 行为不同。它读取并丢弃所有输入函数,直到第一个换行符或直到 EOF
(由文件结束或错误触发)。无论该输入是否被缓冲,它都会执行此操作。
例如,假设您键入字符 hello
(没有换行符),然后您的程序调用 fflush(stdin)
、,然后 您输入换行符.
fflush(stdin)
,鉴于 Linux 记录的行为,将立即丢弃 hello
和 return,留下换行符以供稍后调用读取。它 "flushes" stdin
在某种意义上它会丢弃所有待处理的输入,无论它是什么。
您的 flushstdin()
函数将读取并丢弃 hello
,然后等待您键入 Enter(或 Ctrl-D), 然后阅读并丢弃它。它读取并丢弃直到换行符或 EOF 的所有输入,无论它在调用时是否处于挂起状态。
同样,fflush(stdin)
的行为未由 C 标准定义,因此使用它会使您的程序不可移植(并且您的编译器不一定会警告您)。
顺便说一句,"that void stuff"是flushstdin
函数的定义。 fflush
不需要它,因为这是已经为您定义的标准 C 库函数。
两个版本都有问题。
正如已经广泛记录的那样,fflush(stdin)
根据 C 标准具有未定义的行为。使用 flushstdin()
函数的替代方案也好不到哪儿去。我建议一次读取一行标准输入并使用 sscanf()
解析它,所有这些都在您可以根据需要使用的实用函数中:
int readfloat(const char *prompt, float *val) {
char buf[128];
for (;;) {
if (prompt)
fputs(prompt, stdout);
if (!fgets(buf, sizeof(buf), stdin)) {
printf("Premature end of file\n");
return 1;
}
if (sscanf(buf, "%f", val) == 1 && *val > 0)
return 0;
printf("Invalid value.\n");
}
}
int main(void) {
float a, b, c, s = 0;
if (readfloat("Enter value of side A: ", &a))
return 1;
...
}