Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 用c+读取标准数据+;不使用getline_C++_Boost_Boost Asio - Fatal编程技术网

C++ 用c+读取标准数据+;不使用getline

C++ 用c+读取标准数据+;不使用getline,c++,boost,boost-asio,C++,Boost,Boost Asio,我正在尝试转换一个程序(它是vscode和调试之间的桥梁) 这个程序是用C语言编写的 它基于VSO单声道调试代码 () 那么, 在C#中,我可以将标准输入读取为流: byte[] buffer = new byte[BUFFER_SIZE]; Stream inputStream = Console.OpenStandardInput(); _rawData = new ByteBuffer(); while (!_stopRequested) {

我正在尝试转换一个程序(它是vscode和调试之间的桥梁) 这个程序是用C语言编写的

它基于VSO单声道调试代码

()

那么, 在C#中,我可以将标准输入读取为流:

 byte[] buffer = new byte[BUFFER_SIZE];
Stream inputStream = Console.OpenStandardInput();
    _rawData = new ByteBuffer();

        while (!_stopRequested) {
            var read = await inputStream.ReadAsync(buffer, 0, buffer.Length);

            if (read == 0) {
                // end of stream
                break;
            }

            if (read > 0) {
                _rawData.Append(buffer, read);
                ProcessData();
            }
        }
我试试这个:

#define _WIN32_WINNT 0x05017
#define BUFFER_SIZE 4096
#include<iostream>
#include<thread>
#include <sstream>

using namespace std;
class ProtocolServer
{

    private:
        bool _stopRequested;
        ostringstream _rawData;
    public:
        void Start()
        {

            char buffer[BUFFER_SIZE];

            while (!cin.eof())
            {

                cin.getline(buffer,BUFFER_SIZE);

                if (cin.fail())
                {
                    //error
                    break;
                }
                else
                {
                    _rawData << buffer;
                }

            }
        }

};

int main()
{
    ProtocolServer *server = new ProtocolServer();
    server->Start();
    return 0;

}
这将正确读取前两行。由于协议没有将\n放在末尾,因此它在3交互中卡在cin.getline中

切换到read()会导致它在cin.read()处停止,并且根本不读取任何内容

我发现了一些类似的问题:

例如:

但我不需要它必须是异步的,但它可以在windows和linux上工作

我为我的英语感到抱歉

谢谢

您需要的是无格式输入操作

这里是一个仅使用std::iostream的1:1翻译。唯一的“把戏”是使用和尊重:

请注意,
!good()
还捕获了
eof()
,因此您可以

if (!inputStream.good()) { break; } // failure or end of stream
现场演示

#include <iostream>
#include <vector>
#include <atomic>

struct Foo {

    void bar() {
        std::vector<char> buffer(BUFFER_SIZE);
        auto& inputStream = std::cin;
        _rawData = std::string {};

        while (!_stopRequested) {
            inputStream.read(buffer.data(), buffer.size());
            auto read = inputStream.gcount();

            if (read > 0) {
                _rawData.append(buffer.begin(), buffer.begin() + read);
                ProcessData();
            }

            if (!inputStream.good()) { break; } // failure or end of stream
        }
    }
  protected:
    void ProcessData() {
        //std::cout << "got " << _rawData.size() << " bytes: \n-----\n" << _rawData << "\n-----\n";
        std::cout << "got " << _rawData.size() << " bytes\n";
        _rawData.clear();
    }

    static constexpr size_t BUFFER_SIZE = 128;
    std::atomic_bool _stopRequested { false };
    std::string _rawData;
};

int main() {
    Foo foo;
    foo.bar();
}

我试着使用boost asio和istream.read,但在这两个方面都没有太大的成功。和你为什么没有成功?也许你的尝试有问题?请提供您尝试的内容,并解释您获得的功能不符合您期望的原因。我不是C#guru,但如果我没有弄错,请等待块,直到异步操作完成。您应该能够使用
std::cin.read(buffer,sizeof(buffer))
,假设缓冲区是一个静态分配的数组。@user4581301,我尝试使用cin.read,但仍停留在这一行。现在我知道你想要什么了,
cin
要么太愚蠢,要么太聪明,这取决于你如何看待它,来做你想做的事情。它将始终查找下一个字节、下一个分隔符或您发送它的任何内容。我的道歉让你走上了一条不好的道路。我想你必须使用特定于操作系统的(CreateFile、ReadConsoleInput和WaitSingleObject,超时时间很短)或使用Boost asio,这两者我都没有用过,但谷歌教授可能有一些有用的提示。例如:看起来我错了一半,我在给出答案时考虑过这一点。这就是我所做的,读取一个未知大小的文件,将其转储到套接字或其他输出中,而我不关心大小。我挂断了没有关闭
cin
,第三个想法是这看起来不是一个要求。@user4581301是的,我没有看到
dispose
使用(inputStream)
。无论如何,这可能意味着它只会关闭流实例。总之,
inputStream.close()
也不难拼写:)我应该问OP而不是假设的经典例子。遗憾的是,你不能指望
istream::readsome
的跨平台行为,因为你认为这正是我需要的。@user4581301:)@sehe这正是我需要的。我在Windows上测试了它,它工作得很好,我很快就会在linux上测试。非常感谢你。
if (inputStream.eof()) { break; }   // end of stream
if (!inputStream.good()) { break; } // failure
if (!inputStream.good()) { break; } // failure or end of stream
#include <iostream>
#include <vector>
#include <atomic>

struct Foo {

    void bar() {
        std::vector<char> buffer(BUFFER_SIZE);
        auto& inputStream = std::cin;
        _rawData = std::string {};

        while (!_stopRequested) {
            inputStream.read(buffer.data(), buffer.size());
            auto read = inputStream.gcount();

            if (read > 0) {
                _rawData.append(buffer.begin(), buffer.begin() + read);
                ProcessData();
            }

            if (!inputStream.good()) { break; } // failure or end of stream
        }
    }
  protected:
    void ProcessData() {
        //std::cout << "got " << _rawData.size() << " bytes: \n-----\n" << _rawData << "\n-----\n";
        std::cout << "got " << _rawData.size() << " bytes\n";
        _rawData.clear();
    }

    static constexpr size_t BUFFER_SIZE = 128;
    std::atomic_bool _stopRequested { false };
    std::string _rawData;
};

int main() {
    Foo foo;
    foo.bar();
}
got 128 bytes
got 128 bytes
got 128 bytes
got 128 bytes
got 128 bytes
got 128 bytes
got 128 bytes
got 92 bytes