【问题标题】:How to get size of data available thru stdin with C++ [duplicate]如何使用 C++ 通过标准输入获取可用数据的大小 [重复]
【发布时间】:2013-01-29 12:43:28
【问题描述】:

如果我从这样的控制台应用程序中获得stdin 的句柄:

HANDLE hStdIn = ::GetStdHandle(STD_INPUT_HANDLE);

然后我可以从中读取数据:

BYTE buff[32];
DWORD dwcbRead = 0;
BOOL bReadRes = ::ReadFile(hStdIn, buff, SIZEOF(buff), &dwcbRead, NULL);

我的问题是,我如何在读取它们之前知道有多少字节可用?

附言。如果没有数据可供读取,ReadFile 似乎会阻塞。

【问题讨论】:

  • 不完全重复的问题。当 stdin 被重定向时,引用的链接(另一个问题)仅解决部分问题。 Anton Kovalenko 的回答向我们展示了PeekConsoleInput 可用于控制台标准输入。我们应该结合答案。

标签: c++ winapi console-application stdin


【解决方案1】:

使用ReadConsoleInput 读取原始输入事件并使用PeekConsoleInput 检查它们而不从输入队列中删除。这里有很多警告:

  1. 您的标准输入可能会被重定向,然后您必须确定其类型并采取相应措施。如果它是一个文件,它不会阻塞,你只需继续阅读。如果是管道,PeekNamedPipe 会提供一些帮助。

  2. 输入事件和字符之间没有一一对应的关系。

  3. 如果在控制台上设置了ENABLE_LINE_MODE,如果还没有输入换行符,ReadFile/ReadConsole 将阻塞;另外,在你真正调用ReadConsole之前,行编辑工具是不可用的,当你调用ReadConsole时,它会阻塞。

我建议在单独的线程中执行 ReadFileReadConsole(或尝试使用后者回退到前者)。您的主线程可能会做一些有用的事情并最终检查(或等待)读取线程的就绪情况。

【讨论】:

    【解决方案2】:

    是的,你可以这样做,是的,它会坐在那里等待你的输入来填充缓冲区。如果这不是你想要的,那么不要使用 ReadFile。

    还有其他用于读取控制台 I/O 的函数,包括为您提供待处理“事件”数量的函数。

    Console IO functions

    【讨论】:

      【解决方案3】:

      对于控制台输入,您不知道用户或机器可以传递多少字符。
      例如,我的程序要求你输入一个句子。你在想哪句话?你会打哪一个?句子中有多少个字母?

      如果你真的想知道,我强烈推荐一门阅读思想的课程,或者在非人类输入的情况下,一门预测未来的课程。

      对于文件,您可以检查大小。

      【讨论】:

      • 我明白你的意思。但是,你不正确。据说PeekNamedPipe 可以根据 Remy Lebeau 的帖子为您提供该信息。
      • @ahmd0:哪个平台? PeekNamedPipe 是标准 C++ 语言的一部分吗?另外,PeekNamedPipe 如何知道我打算输入多少个字符?连我自己都不知道!
      • 我认为 PeekNamedPipe 带有新的 Microsoft MRT...(读心技术。)所以它知道你会输入什么,甚至在你输入之前。
      【解决方案4】:

      【讨论】:

      • 哈哈。我自己也看到了PeekNamedPipe,但因为它的名字,我想,“这不可能。”但是你会知道什么。它似乎确实有效。尽管由于某些奇怪的原因,如果没有输入,它会返回 FALSE 并且 GetLastError 设置为 ERROR_INVALID_HANDLE...嗯。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-06
      • 2011-05-04
      • 1970-01-01
      • 2018-01-24
      • 1970-01-01
      • 2018-05-09
      相关资源
      最近更新 更多