我无法刷新标准输入。如何在 C 中刷新标准输入?

发布于 2024-08-20 04:58:44 字数 737 浏览 7 评论 0原文

如何刷新标准输入

为什么它在下面的代码片段中不起作用?

#include <string.h>
#include <stdio.h>
#include <malloc.h>
#include <fcntl.h>

int main() {
    int i = 0, j = 0, sat;
    char arg[256];
    char *argq;
    argq = malloc(sizeof(char) * 10);
    
    printf("Input the line\n");
    i = read(0, arg, sizeof(char) * 9);
    arg[i - 1] = '\0';
    fflush(stdin);
    
    i = read(0, argq, sizeof(char) * 5);
    argq[i - 1] = '\0';

    puts(arg);
    puts(argq);
    
    return 0;
}

现在,如果我输入 11 个字符,则只应读取 9 个字符,但 stdin 中的其余两个字符不会刷新并在 argq 中再次读取。为什么?

输入:123 456 789

输出:

123 456
89

为什么我会得到这个 89 作为输出?

How to flush the stdin??

Why is it not working in the following code snippet?

#include <string.h>
#include <stdio.h>
#include <malloc.h>
#include <fcntl.h>

int main() {
    int i = 0, j = 0, sat;
    char arg[256];
    char *argq;
    argq = malloc(sizeof(char) * 10);
    
    printf("Input the line\n");
    i = read(0, arg, sizeof(char) * 9);
    arg[i - 1] = '\0';
    fflush(stdin);
    
    i = read(0, argq, sizeof(char) * 5);
    argq[i - 1] = '\0';

    puts(arg);
    puts(argq);
    
    return 0;
}

Now if I give the input as 11 characters, only 9 should be read but the remaining two characters in the stdin are not flushed and read again in the argq. Why?

Input: 123 456 789

Output:

123 456
89

Why am I getting this 89 as the output?

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

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

发布评论

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

评论(8

表情可笑 2024-08-27 04:58:44

我相信 fflush 仅用于输出流。

您可以尝试 fpurge__fpurge。请注意,fpurge 是非标准且不可移植的。您可能无法使用它。

来自 Linux fpurge 手册页:通常想要丢弃输入缓冲区是一个错误。

用于刷新标准输入的最便携的解决方案可能是以下内容:

int c;
while ((c = getchar()) != '\n' && c != EOF);

I believe fflush is only used with output streams.

You might try fpurge or __fpurge on Linux. Note that fpurge is nonstandard and not portable. It may not be available to you.

From a Linux fpurge man page: Usually it is a mistake to want to discard input buffers.

The most portable solution for flushing stdin would probably be something along the lines of the following:

int c;
while ((c = getchar()) != '\n' && c != EOF);
贱人配狗天长地久 2024-08-27 04:58:44
int c;
while((c = getchar()) != '\n' && c != EOF);

这就是我清除输入缓冲区的方法。

int c;
while((c = getchar()) != '\n' && c != EOF);

Is how I'd clear the input buffer.

迟月 2024-08-27 04:58:44

如何刷新标准输入?

刷新输入流正在调用未定义的行为。不要尝试。

您只能刷新输出流。

How to flush the stdin??

Flushing input streams is invoking Undefined Behavior. Don't try it.

You can only flush output streams.

感性不性感 2024-08-27 04:58:44

您将使用 '\0' 覆盖 arg 中输入的最后一个元素。该行应该是 arg[i]='\0'; (在错误和边界检查之后,您丢失了。)

其他人已经评论了刷新部分。

You are overriding the last element of the input in arg with '\0'. That line should be arg[i]='\0'; instead (after error and boundary checking you are missing.)

Other's already commented of the flushing part.

多像笑话 2024-08-27 04:58:44

如果你使用 GLIBC,你可以手动搞乱 stdin ptr

void flush_stdin(){
    unsigned long* tmpstdin = (unsigned long*)stdin;
    unsigned long* oldbuf = (unsigned long*)*(tmpstdin+4);
    free((void*)oldbuf);
    *tmpstdin=(unsigned long)0xfbad2088;
    tmpstdin+=1;
    memset(tmpstdin,'\x00',64);
}

If you use GLIBC you can just mess with the stdin ptr manually

void flush_stdin(){
    unsigned long* tmpstdin = (unsigned long*)stdin;
    unsigned long* oldbuf = (unsigned long*)*(tmpstdin+4);
    free((void*)oldbuf);
    *tmpstdin=(unsigned long)0xfbad2088;
    tmpstdin+=1;
    memset(tmpstdin,'\x00',64);
}
望喜 2024-08-27 04:58:44

在 Linux 中,如果不遇到命令在某些情况下开始等待输入的情况,就无法清理 stdin。解决这个问题的方法是将所有 std::cin 替换为 readLineToStdString():

void readLine(char* input , int nMaxLenIncludingTerminatingNull )
{
    fgets(input, nMaxLenIncludingTerminatingNull , stdin);

    int nLen = strlen(input);

    if ( input[nLen-1] == '\n' )
        input[nLen-1] = '\0';
}

std::string readLineToStdString(int nMaxLenIncludingTerminatingNull)
{
    if ( nMaxLenIncludingTerminatingNull <= 0 )
        return "";

    char* input = new char[nMaxLenIncludingTerminatingNull];
    readLine(input , nMaxLenIncludingTerminatingNull );

    string sResult = input;

    delete[] input;
    input = NULL;

    return sResult;
}

这也将允许您在 std::cin 字符串中输入空格。

You can't clean stdin in Linux without bumping into scenarios that the command will start waiting for input in some cases. The way to solve it is to replace all std::cin with readLineToStdString():

void readLine(char* input , int nMaxLenIncludingTerminatingNull )
{
    fgets(input, nMaxLenIncludingTerminatingNull , stdin);

    int nLen = strlen(input);

    if ( input[nLen-1] == '\n' )
        input[nLen-1] = '\0';
}

std::string readLineToStdString(int nMaxLenIncludingTerminatingNull)
{
    if ( nMaxLenIncludingTerminatingNull <= 0 )
        return "";

    char* input = new char[nMaxLenIncludingTerminatingNull];
    readLine(input , nMaxLenIncludingTerminatingNull );

    string sResult = input;

    delete[] input;
    input = NULL;

    return sResult;
}

This will also allow you to enter spaces in std::cin string.

幻梦 2024-08-27 04:58:44

在 Windows 中,您可以使用倒带(stdin)功能。

In Windows you can use rewind(stdin) fuction.

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