Итак, что я пытаюсь сделать, это создать функцию в C ++, которая позволяет пользователю вводить все и вся в строку в течение заданного промежутка времени (скажем, десять минут (или даже одну)) (и сохраняйте все, что они вводили, Кстати. Я пытаюсь разработать игру, чтобы помочь участникам или авторам NaNoWriMo в целом подтолкнуть их к написанию, поэтому держать все необходимо) и затем не позволяет больше ввода для добавления. Поначалу это звучало легко, но пять часов поиска в Google показали обратное.
Во-первых, я подумал, что могу просто добавлять несколько раз, пока не закончится время или что-то в этом роде. Заметим:
int main() //testing
{
string str;
string app = " ";
getline(cin, app);
for (int i = 0; i <= 3; i++)
{
Sleep(5000);
cout << i << endl;
str = " ";
getline(cin, str);
app.append(str);
}
cout << app;
}
Но потом я понял, Дух, что цикл не будет проверять условие снова, пока пользователь не нажмет ввод. Надоедливый. То же самое с моим умным представлением о характере. Мне был нужен цикл, который обновлялся с каждым набранным символом (или с каждым вторым прошедшим), независимо от того, сколько времени требуется пользователю, чтобы набрать другой.
Итак, тогда я подумала: «Ну, останавливаться на каждом месте и обновлять время должно работать достаточно хорошо, да?»
Именно тогда я начал обнаруживать, что C ++ не очень хорошо работает с синтаксическим анализом строк или чтением ввода по мере его поступления. Я думал о добавлении каждого персонаж, так как это довольно легко найти место, но это еще ждет пользователя.
Разочарованный, я задался вопросом, есть ли способ запустить программу одновременно с получением пользовательского ввода, чтобы один раз закончилось (используя время (ноль), Время проходит, время (ноль) и вычитая две переменные, чтобы получить прошедшие секунды).
Оказывается, есть! (Я знал там имел быть, учитывая все компьютерные программы и игры, которые используют этот принцип, но я довольно плохо знаком с программированием (я узнал, функции в прошлую среду, чтобы дать вам представление), так что я не знал, какие.)
Первыми функциями, на которые я наткнулся, были проклятия и ncurses, но я быстро обнаружил, что это действительно не было жизнеспособным вариантом для того, что я хочу делать (так как я слышал, что делать довольно забавные вещи для cout).
затем Я наткнулся на kbhit, который распознает нажатия клавиш на клавиатуре. Этот блог кажется многообещающим, и, вероятно, что я хочу сделать, но я не уверен, на каком языке это написано. , , все, что я знаю, это то, что он не очень хорошо работает с моей C ++ IDE. Я понятия не имею, как заставить это играть хорошо с C ++.
Итак, повторение того, что я хотел бы:
Цикл, который содержит одновременное выполнение счетчика времени и пользовательского ввода (в строку), но завершается (перестает позволять вводить пользователем дальше в строку), когда время истекает. (Все, не делая смешных вещей с остальной частью моей программы, как ncurses.)
Дополнительно: я использую Windows 8 (проклятие моего существования) и использую Code :: Blocks в качестве своей IDE.
Или, если у вас есть, где-то на этот вопрос уже был дан ответ. Это было бы здорово. Мне было бы глупо чувствовать, что я не могу его найти.
(Вот несколько мест, на которые я посмотрел по пути:
Пользовательский ввод во время работы программы
Как читать ввод со стандартного ввода, пока не нажата пробел или табуляция?
Захватывать символы со стандартного ввода, не дожидаясь нажатия клавиши ввода )
(Игра, которую я пытаюсь создать, (которая совсем не очень далеко; я начал играть прошлой ночью), если вам интересно: https://github.com/Rowan-Law/Dungeon-Crawl/blob/master/Source%20Code )
Вот как вы можете получить довольно близкое приближение к тому, что вы хотите в C ++ 17, используя многопоточность. Единственный сбой в том, что пользователь все еще может печатать после ограничения по времени, он просто не будет сохранен.
#include <atomic>
#include <chrono>
#include <iostream>
#include <istream>
#include <mutex>
#include <ostream>
#include <string>
#include <thread>
std::atomic_bool done = false;
std::mutex cout_mutex{};
void Timing(std::chrono::seconds length) {
auto start = std::chrono::steady_clock::now();
auto end = start + length;
auto now = std::chrono::steady_clock::now();
while(now < end) {
now = std::chrono::steady_clock::now();
done = false;
}
done = true;
{
std::scoped_lock<std::mutex> lock(cout_mutex);
std::cout << "\nTime's up! Any unsaved input will be lost." << std::endl;
}
}
int main() {
std::string str{};
std::string app{};
using namespace std::literals::chrono_literals;
//This can be any duration you want.
std::thread t = std::thread(Timing, 30s);
t.detach();
while(!done) {
std::getline(std::cin, str);
if(!done) {
app.append(str + '\n');
}
}
std::cout << app;
}
Возможно, вы захотите создать поток для времени, а затем просто обновлять строку до тех пор, пока поток не вернется
Многопоточность — это решение. На базовом уровне консольные приложения C ++, использующие std::cin
только обновление при входе (как я и Кристиан Хакл указали), поэтому без потоков невозможно сделать то, что я хотел.
Я знаю, что этот вопрос довольно старый, но я надеюсь, что этот ответ сэкономит другим новичкам кучу времени в поисках ответа, которого не существует!