Напишите конечную строку в STD :: CIN внешне, чтобы сделать его выходом из блокировки GetLine? [дублировать]C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Напишите конечную строку в STD :: CIN внешне, чтобы сделать его выходом из блокировки GetLine? [дублировать]

Сообщение Anonymous »

РЕДАКТИРОВАТЬ: Можем ли мы повторить вопрос, у меня есть частичный ответ, который я могу опубликовать? И я подумал, что лучший способ справиться с блокирующей природой GetLine - использовать его в потоке. Это действительно отлично подходит для меня - за исключением того, что я не могу остановить поток «внешне» из -за блокировки getLine . Условие, но это основной поток, который хочет, чтобы поток оболочки выключился). Однако, поскольку в то время getLine все еще блокируется, поток не может выйти, поэтому я просто получаю «остановку» - и мне нужно снова нажать Enter, чтобы сделать полный выход, который я нахожу массово раздражающим. Вы можете увидеть то, что я попробовал в приведенном ниже коде, но, к сожалению, это не работает, поскольку мне все еще нужно нажимать введите после «остановки», чтобы получить чистый выход. Ввод - это довольно взломан. /> < /blockquote>
попробовал это, не мог заставить класс для компиляции сначала, но даже позже, что я должен с этим делать? Иметь IDCIN IDCIN (std :: cin, myString) staction stamentiation, а затем используйте idcin , где бы я ни использовал std :: cin ? А что, что, я просто присваиваю myString и cin в конечном итоге выводит его? В любом случае, не удалось заставить это работать. и если вы делаете cin.rdbuf (file.rdbuf ()); at at start - но не если вы хотите изменить поведение во время выполнения (т.е. вы начали использовать cin нормально, а затем хотите, чтобы он выводил файл после некоторого времени; и все же, не хотите файл, нужна строка). /> Вместо того, чтобы облажаться с CIN, вы можете, чтобы ваша программа приняла общую std :: iStream & < /code>. При нормальном запуске просто передайте это cin . Во время модульного теста пропустите его по потоку ввода/вывода вашего собственного творения. Кроме того, возможно, это относится к отдельным экземплярам iStream (то есть cin для нормального запуска программы, что -то еще для тестового запуска) - здесь я бы хотел написать в cin в той же программе. PrettyPrint-Override ">int main() {
using namespace std;
streambuf *backup;
istringstream oss("testdata");
backup = cin.rdbuf();
cin.rdbuf(oss.rdbuf());
string str;
cin >> str;
cout sputn("\r\n", 2);
std::cin.putback('\n');
if (tj.joinable())
{
tj.join();
}
}

void ShellThread::blocking_process_shell(void) {
while( active.load() ) {
printf("> ");
std::getline(std::cin, in_repl_cmd); // detects single press ENTER, and blocks
std::cin.clear();
printf("# %s\n", in_repl_cmd.c_str()); // echo response
}
}

int main(void) {
myshell.start();
std::this_thread::sleep_for(std::chrono::milliseconds(4000));
myshell.stop();
return EXIT_SUCCESS;
}

Итак, что я пытался сделать: std :: cin.clear () , поэтому любые предыдущие ошибки очищаются, а затем попытались записать непосредственно в rdbuf cin с std :: cin.rdbuf ()-> sputn ("\ r \ n", 2); std :: cin.putback ('\ n'); -ничего из этого не помогает с текущим поведением программы:
$ ./test.exe
> hello
# hello
> there
# there
> STOPPING # blocks indefinitely here, have to press ENTER or Ctrl-C *again* if I want it to exit
#

$

В конце концов, я даже не забочусь о том, чтобы писать все так много, все, что я хочу, - это заставить Getline выйти чисто - если бы был метод std :: cin.close () , я думаю, что это можно было бы так или иначе. Или прокси, чтобы заставить getLine < /code> выйти из блокировки ждать? Я собирался написать комментарий, но зачем беспокоиться, никто не заботится достаточно, чтобы больше читать достаточно, чтобы определить, действительно ли вопрос является дубликатом, я думаю, просто с ИИ. Ну, вот вы, тогда: < /p>
// test.cpp

#include // std::cin, std::cout
#include // std::ostringstream
#include // std::ifstream
#include
#include // std::thread
#include // std::atomic
#include // std::istringstream
//#include
#include
#include // std::mutex

// same code with either of these headers:
//#include // Windows only, _getch + kbhit;
#include "linux_conio/linux_conio.h" // git clone https://github.com/Flawww/linux_conio.git

// compile with:
// g++ -g -std=c++11 test.cpp -o test.exe -pthread # Windows
// g++ -g -std=c++11 linux_conio/linux_conio.cpp test.cpp -o test.exe -pthread

class AsyncGetline // https://stackoverflow.com/q/42264216
{
public:
//AsyncGetline is a class that allows for asynchronous CLI getline-style input
//(with 0% CPU usage!), which normal iostream usage does not easily allow.
AsyncGetline()
{
input = "";
sendOverNextLine = true;
continueGettingInput = true;

tj = std::thread([&]()
{
in_thread = true;
//Non-synchronized string of input for the getline calls.
std::string synchronousInput;
char nextCharacter;
int charsRead = 0;
int did_kbhit = 0;

//Get the asynchronous input lines.
do
{
//Start with an empty line.
synchronousInput = "";

//Process input characters one at a time asynchronously, until a new line character is reached.
while (continueGettingInput.load())
{
while( continueGettingInput.load() and (!(did_kbhit = kbhit())) ) {
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
if (did_kbhit) {
nextCharacter = _getch(); // note, on Windows, on Enter, getting '\r' first (and only)!
//printf(" %d ", nextCharacter);
if (nextCharacter == '\r') {
putchar('\n');
} else {
putchar(nextCharacter);
}
}

//Check for new line character.
// _getch reports '\r', even for copy-paste of CRLF lines
if ((nextCharacter == '\n') or (nextCharacter == '\r'))
{
break;
}

//Since this character is not a new line character, add it to the synchronousInput string.
synchronousInput += nextCharacter;
} // end while

//Be ready to stop retrieving input at any moment.
if (!continueGettingInput.load())
{
break;
}

//Wait until the processing thread is ready to process the next line.
while (continueGettingInput.load() && !sendOverNextLine)
{
//Ensure that the other thread is always yielded to when necessary. Don't sleep here;
//only yield, in order to ensure that the processing will be as responsive as possible.
std::this_thread::yield();
}

//Be ready to stop retrieving input at any moment.
if (!continueGettingInput.load())
{
break;
}

//Safely send the next line of input over for usage in the processing thread.
inputLock.lock();
input = synchronousInput;
inputLock.unlock();

//Signal that although this thread will read in the next line,
//it will not send it over until the processing thread is ready.
sendOverNextLine = false;
} // end do
while (continueGettingInput.load()); // && input != "exit"
in_thread = false;
}); //.detach();
}

//Stop getting asynchronous CLI input.
~AsyncGetline()
{
//Stop the getline thread.
printf("~AsyncGetline destructor 1\n");
continueGettingInput = false;
if (tj.joinable()) {
printf("~AsyncGetline destructor 2\n");
tj.join();
}
}

//Get the next line of input if there is any; if not, sleep for a millisecond and return an empty string.
std::string GetLine()
{
//See if the next line of input, if any, is ready to be processed.
if (sendOverNextLine)
{
//Don't consume the CPU while waiting for input; this_thread::yield()
//would still consume a lot of CPU, so sleep must be used.
std::this_thread::sleep_for(std::chrono::milliseconds(1));

// signal as well
return ">>>NO_LINE ");
fflush(stdout);
prompt_printed = true;
}
if (ag) {
in_repl_cmd = ag->GetLine(); // non-blocking; note: we get empty string here, regardess of if we just pressed ENTER, or if there was no line! though now it says ">>>NO_LINENO_LINE

Подробнее здесь: https://stackoverflow.com/questions/795 ... ng-getline
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»