我找到了this question,它詢問如何異步讀取輸入,但只適用於POSIX流描述符,這在Windows上不起作用。所以,我發現this tutorial這表明,而不是使用POSIX流描述符,我可以使用boost::asio::windows::stream_handle
。如何在Windows中使用boost asio異步讀取命令行輸入?
下面兩個例子中,我想出了下面的代碼。當我運行它時,我無法在命令提示符中輸入任何內容,因爲程序立即終止。我希望它能夠捕獲來自用戶的任何輸入,可能是std::string
,同時允許我的程序中的其他邏輯執行(即從Windows控制檯執行異步I/O)。
本質上講,我試圖避免擋住了我的程序時,它試圖從stdin
閱讀。我不知道這是否可以在Windows中使用,因爲我還發現了this post,它詳細描述了另一個用戶在嘗試做同樣的事情時遇到的問題。
#define _WIN32_WINNT 0x0501
#define INPUT_BUFFER_LENGTH 512
#include <cstdio>
#include <iostream>
#define BOOST_THREAD_USE_LIB // For MinGW 4.5 - (https://svn.boost.org/trac/boost/ticket/4878)
#include <boost/bind.hpp>
#include <boost/asio.hpp>
class Example {
public:
Example(boost::asio::io_service& io_service)
: input_buffer(INPUT_BUFFER_LENGTH), input_handle(io_service)
{
// Read a line of input.
boost::asio::async_read_until(input_handle, input_buffer, "\r\n",
boost::bind(&Example::handle_read, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void handle_read(const boost::system::error_code& error, std::size_t length);
void handle_write(const boost::system::error_code& error);
private:
boost::asio::streambuf input_buffer;
boost::asio::windows::stream_handle input_handle;
};
void Example::handle_read(const boost::system::error_code& error, std::size_t length)
{
if (!error)
{
// Remove newline from input.
input_buffer.consume(1);
input_buffer.commit(length - 1);
std::istream is(&input_buffer);
std::string s;
is >> s;
std::cout << s << std::endl;
boost::asio::async_read_until(input_handle, input_buffer, "\r\n",
boost::bind(&Example::handle_read, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else if(error == boost::asio::error::not_found)
{
std::cout << "Did not receive ending character!" << std::endl;
}
}
void Example::handle_write(const boost::system::error_code& error)
{
if (!error)
{
// Read a line of input.
boost::asio::async_read_until(input_handle, input_buffer, "\r\n",
boost::bind(&Example::handle_read, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
}
int main(int argc, char ** argv)
{
try {
boost::asio::io_service io_service;
Example obj(io_service);
io_service.run();
} catch(std::exception & e)
{
std::cout << e.what() << std::endl;
}
std::cout << "Program has ended" << std::endl;
getchar();
return 0;
}
我不是一個Windows用戶,但是不會使用\ r \ n作爲新的線路指示器嗎? –
是的,但會阻止它的工作,因爲\ n仍然在換行符序列中?我將分隔符字符串更改爲「\ r \ n」,結果相同。 – nickb
哪裏可以調用io_service :: run()? –