C++ 用c+读取标准数据+;不使用getline
我正在尝试转换一个程序(它是vscode和调试之间的桥梁) 这个程序是用C语言编写的 它基于VSO单声道调试代码 () 那么, 在C#中,我可以将标准输入读取为流: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) {
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