Я нашел этот вопрос , который спрашивает, как читать ввод асинхронно, но будет работать только с дескрипторами потока POSIX, которые не будут работать в Windows.Итак, я нашел этот урок , который показывает, что вместо использования потокового дескриптора POSIX я могу использовать boost::asio::windows::stream_handle
.
. Следуя обоим примерам, я придумал приведенный ниже код.Когда я запускаю его, я ничего не могу набрать в командной строке, так как программа немедленно завершает работу.Я бы хотел, чтобы он захватывал любые входные данные от пользователя, возможно, в std::string
, позволяя при этом выполнять другую логику в моей программе (т.е. выполнять асинхронный ввод-вывод из консоли Windows).
По существу,Я пытаюсь избежать блокировки моей программы, когда она пытается прочитать из stdin
.Я не знаю, возможно ли это в Windows, поскольку я также обнаружил этот пост , в котором подробно описываются проблемы, с которыми столкнулся другой пользователь при попытке сделать то же самое.
#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;
}