我可以在 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 读取?
我不认为使用 _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;
}```