为什么Windows的_read()函数无法从STDOUT读取?

问题描述 投票:0回答:1

我可以在 Linux 上从 STDOUT 读取(),但在 Windows 中,我只能从 STDIN 读取并写入 STDOUT。

下面是代码,我在Windows上使用:

#include <io.h>  // Include for _read()
#include <stdio.h>
#include <string.h>
#include <stdio.h>

int main() {
    char buffer[256];
    int n;
    int fd = 1; // File descriptor for stdout (standard output)

    while ((n = _read(fd, buffer, sizeof(buffer) - 1)) > 0) {
        buffer[n] = '\0'; // Null-terminate the string if needed
        char* p = buffer;
        char* nl;

        while ((nl = strchr(p, '\n')) != NULL) {
            *nl = '\0'; // Null-terminate the line
            printf("Line: %s\n", p); // Process the line
            p = nl + 1; // Move to the next line
        }

        // If there's any remaining data in the buffer, process it
        if (*p != '\0') {
            printf("Remaining: %s\n", p);
        }
    }

    if (n == 0) {
        // End of input (Ctrl+Z on Windows)
        printf("End of input reached. Program exiting.\n");
    }
    else {
        perror("Error reading from stdin");
    }

    return 0;
}

我得到的错误是:从 fd 读取时出错:错误的文件描述符。

但在 Linux 中,我也可以在 stdout 上提供输入并写入。为什么 Windows 中的行为有所不同? 有没有办法,我们可以使用 _read 从 Windows 上的 stdout 读取?

c windows visual-c++ msvcrt
1个回答
0
投票

我不认为使用 _read 是一个好的选择,如果你希望你的读取是非阻塞的,有一个名为 O_NONBLOCK 的选项用于读取。

函数 _read 不是线程安全的,并且 _read 不允许读取固定数量的字节,因此读取更好。

请注意,当您在非阻塞模式下使用 read 时,read 函数将不会等待输入,如果您等待 1 秒直到按下某个键,read 函数将完成大量 0 字节的读取,但您不想这样做接受它作为输入,因此我们检查读取的字节数是否等于 0,如果是,我们就继续循环。

#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

int main() {
  char buffer[256];
  int n;
  int fd = stdout->_fileno;

  // Here we set the file descriptor to non-blocking mode using fcntl
  int flags = fcntl(fd, F_GETFL, 0);
  flags |= O_NONBLOCK;
  fcntl(fd, F_SETFL, flags);

  while (1) {
    n = read(fd, buffer, sizeof(buffer) - 1);
    if (n == -1) {
      if (errno == EAGAIN) {
        // We don't have any data to read so we can continue
        continue;
      } else {
        perror("read");
        return 1;
      }
    } else if (n == 0) {
      // End of input
      printf("End of input reached. Program exiting.\n");
      return 0;
    }

    buffer[n] = '\0';
    char* p = buffer;
    char* nl;

    while ((nl = strchr(p, '\n')) != NULL) {
      *nl = '\0';
      printf("Line: %s\n", p);
      p = nl + 1;
    }

    // Its possible that we have a partial line left in the buffer
    if (*p != '\0') {
      printf("Remaining: %s\n", p);
    }
  }

  return 0;
}```
© www.soinside.com 2019 - 2024. All rights reserved.