fgets在换行符之前设置null char后清除输入流 [英] Clear input stream after fgets set null char before newline

查看:49
本文介绍了fgets在换行符之前设置null char后清除输入流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个程序,用户输入两个输入.由于我无法控制用户输入的内容,因此用户可以超过数组的固定大小.由于 fgets() appends 会在空字符之前保留换行符的结尾,因此如果用户超出预期大小时换行符无法容纳,则该空字符截断输入.当用户点击Enter时,换行符是否仍存在于输入流中?如果是这样,这是为什么 fgets()由于第一次输入中的换行符而第二次跳过的原因吗?

I have a program where the user enters two inputs. Being that I can't control what the user enters, the user can go past the fixed size of the array. Since fgets() appends retains a newline to the end before the null character, in the event that a newline cannot fit when the user goes beyond the intended size, the null character truncates the input. Does the newline character when the user hits enter still exist in the input stream? If so, is this the reason why fgets()skips the second time because of the newline from the first input?

#include <stdio.h>
int main(){
    char str[5];
    fgets(str,5,stdin);
    printf("Output:%s",str);

    fgets(str,5,stdin);
    printf("Output:%s",str);

    return 0;
}

示例输入 ABCDE \ n

输出

Output:ABCDOutput:E

在阅读了这样的答案之后, fgets()不会提示用户第二次时间,问题似乎不是通过 fflush(stdin)刷新输入流,但我听到了相互矛盾的信息,因为这会导致不确定的行为.我的最后一个问题是,如果是导致问题的保留换行符,清除输入流的合适方法是什么?

After reading this SO answer fgets() isn't prompting user a second time , the issue seems to be not flushing the input stream via fflush(stdin), but I've heard conflicting information saying as this leads to undefined behavior. My last question is, what would be the appropriate way to clear the input stream if it's the retained newline that's causing issues?

推荐答案

用户可以超过数组的固定大小.由于 fgets()在空字符之前在末尾添加换行符

the user can go past the fixed size of the array. Since fgets() appends a newline to the end before the null character

不,不是.它将从输入中读取的字符写到提供的缓冲区中,直到并包括第一行,或者直到指定的缓冲区大小用完(字符串终止符的字节数少于一个),或者直到发生错误为止或到达流的末尾,以先到者为准.新行不是由 fgets()发明的;它来自输入.

No, it does not. It writes characters read from the input into the provided buffer, up to and including the first newline, or until the specified buffer size is exhausted (less one byte for the string terminator), or until an error occurs or the end of the stream is reached, whichever comes first. The newline is not invented by fgets(); it comes from the input.

,如果用户超出预期大小时换行符无法容纳,则空字符会截断输入.当用户点击Enter时,换行符是否仍存在于输入流中?

, in the event that a newline cannot fit when the user goes beyond the intended size, the null character truncates the input. Does the newline character when the user hits enter still exist in the input stream?

用户输入的所有未复制到缓冲区的字符都将等待在流中读取.如果用户输入了换行符,则其中将包括换行符.

All characters entered by the user and not copied into the buffer remain waiting to be read in the stream. That will include the newline, if the user entered one.

如果是这样,这是因为第一次输入中的换行符导致fgets()第二次跳过的原因吗?

If so, is this the reason why fgets()skips the second time because of the newline from the first input?

fgets()不会跳过,但是会接听上一个调用不再将字符从输入传递到缓冲区的位置.没有字符丢失.这意味着,如果第一次调用未返回全部内容,则第二次调用返回第一条输入行的一部分.您需要以一种或另一种方式考虑输入可能与行长期望不符的可能性.

fgets() does not skip, but it does pick up where the previous call left off transferring characters from input to the buffer. No characters are lost. That means that the second call returns part of the first input line if the first call did not return the whole thing. You need to account one way or another for the possibility that the input does not conform to your line-length expectations.

问题似乎不是通过 fflush(stdin)

不,不是.刷新用于将缓冲的 output 发送到基础输出设备.刷新输入流会产生未定义的行为.原则上,这可能表现为缓冲区转储,并且给定的实现甚至可以指定这种行为, ,但您不希望这样做 ,因为缓冲的数据可能比你想摆脱.

No, it isn't. Flushing is for sending buffered output to the underlying output device. Flushing an input stream produces undefined behavior. In principle, that could manifest as a buffer dump, and a given implementation might even specify such behavior, but you don't want that because there may be more data buffered than you want to get rid of.

但是我听到了一些相互矛盾的信息,因为这会导致不确定的行为.我的最后一个问题是,如果是导致问题的保留换行符,清除输入流的合适方法是什么?

but I've heard conflicting information saying as this leads to undefined behavior. My last question is, what would be the appropriate way to clear the input stream if it's the retained newline that's causing issues?

您从输入中读取内容,直到您读取换行符为止.有很多I/O功能可供选择,以完成此任务. fgets()本身可能很方便,因为您已经在使用它:

You read from the input until you've read the newline. There are plenty of I/O functions to choose from to accomplish this. fgets() itself might prove convenient, since you're already using it:

char str[5];

if (fgets(str, 5, stdin)) {
    printf("Output:%s", str);
    // read and consume the tail of the line, if any (overwrites str)
    while (!strchr(str, '\n') && fgets(str, 5, stdin)) { /* empty */ }
}

这篇关于fgets在换行符之前设置null char后清除输入流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆