std::cin.read() 无法读取流

问题描述

我正在为浏览器扩展实现 native host。我围绕 std::cin 而不是 C 风格的 getchar()

设计了我的实现

这里的问题是 std::cin 没有以二进制模式打开,这对基于 Windows 的主机有影响,因为 Chrome 浏览器不适用于 Windows 样式 \r\n 因此我必须以二进制方式阅读它模式。

要以二进制模式读取,我必须使用 _setmode(_fileno(stdin),_O_BINARY);

我的 IDE 找不到 _fileno 的定义,我发现解决方法是使用以下宏,

#if !defined(_fileno)
#define _fileno(__F) ((__F)->_file)
#endif

但是,我对这个宏不够自信。我认为有问题,但我使用的是最新的 MinGW 编译器,但不确定为什么没有定义。

更新:该函数似乎在 __STRICT_ANSI__ 后面,我不知道如何禁用它。

无论如何,程序编译良好,浏览器启动它,当我从浏览器发送消息时,应用程序能够读取消息的长度,当它尝试读取内容时,std::cin.read() 操作插入缓冲区向量没有任何内容,消息也不是空终止的,但我认为这不会导致问题。

我还尝试在没有阅读的情况下向浏览器发送一条虚拟消息,但它似乎冻结了浏览器。

#include <iostream>
#include <cstdio>
#include <string>
#include <vector>

#ifdef __WIN32
#include <fcntl.h>
#include <io.h>
#endif

#if !defined(_fileno)
#define _fileno(__F) ((__F)->_file)
#endif

enum class Platforms {
    macOS = 1,Windows = 2,Linux = 3
};

Platforms platform;

#ifdef __APPLE__
    constexpr Platforms BuildOS = Platforms::macOS;
#elif __linux__
    constexpr Platforms BuildOS = Platforms::Linux;
#elif __WIN32
    constexpr Platforms BuildOS = Platforms::Windows;
#endif


void sendMessage(std::string message) {
    auto *data = message.data();
    auto size = uint32_t(message.size());

    std::cout.write(reinterpret_cast<char *>(&size),4);
    std::cout.write(data,size);
    std::cout.flush();
}

int main() {
    if constexpr(BuildOS == Platforms::Windows) {
        // Chrome doesn't deal well with Windows style \r\n
        _setmode(_fileno(stdin),_O_BINARY);
        _setmode(_fileno(stdout),_O_BINARY);
    }

    while(true) {
        std::uint32_t messageLength;

        // First Four contains message legnth
        std::cin.read(reinterpret_cast<char*>(&messageLength),4);

        if (std::cin.eof())
        {
            break;
        }

        std::vector<char> buffer;

        // Allocate ahead
        buffer.reserve(std::size_t(messageLength) + 1);

        std::cin.read(&buffer[0],messageLength);

        std::string message(buffer.data(),buffer.size());

        sendMessage("{type: 'Hello World'}");
    } 
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)