Keep running a program without any intervention till its asked to quit - c++

The below code expects the user to key in a character on every loop. If I want to keep running this loop without user having to enter any character on every loop till the number 0 is keyed in, how do i achieve it.
#include<iostream>
int main()
{
int i = 1;
int ch = 1;
while (ch != 0)
{
std::cin >> ch;
std::cout << "Hi" << i << std::endl;
++i;
}
return 1;
}

Threading is your only possibility. Also it always requires the ENTER when you are using std::cin. This could work:
#include <future>
#include <iostream>
#include <thread>
int main(int argc, char** argv) {
int i = 1;
std::atomic_int ch{1};
std::atomic_bool readKeyboard{true};
std::thread t([&ch, &readKeyboard]() {
while (readKeyboard) {
int input;
if (std::cin >> input) {
ch = input;
if (ch == '0') {
break;
}
}
}
});
while (ch != '0') {
std::cout << "Hi" << i << std::endl;
++i;
}
readKeyboard = false;
t.join();
return 1;
}

You can do this but you will have to use threads. Here is the minimal example how to achive this behaviour. Please note that you will need C++11 at least.
#include <iostream>
#include <thread>
#include <atomic>
int main()
{
std::atomic<bool> stopLoop;
std::thread t([&]()
{
while (!stopLoop)
{
std::cout << "Hi";
}
});
while (std::cin.get() != '0') //you will need to press enter after pressing '0'
{
; //empty loop, just wait until there is 0 on input
}
stopLoop = true; //this stops the other loop
}
Other options will be to dive into OS specific libraries. You must now that C++ doesn't have any kind of non-blocking I/O in standard library and for most time you will have to press <ENTER> to have any input in input stream (std::cin)

Related

How do I make it so no matter how many times the user presses enter with a blank string, it always prints the 'start' string?

This is my code -
How do I make this loop unlimited?
Like any terminal when you press enter with a blank string it rewrites your root
#include <iostream>
#include <windows.h>
std::string input_t;
void startup(std::string start) {
std::cout << start;
while(true) {
while ( n = std::cin.get() ) {
if ( int n == (int)'\n' ) {
std::cout << start;
std::cin >> input_t;
}
else {
std::cout << "Program is terminating...\n";
exit(EXIT_FAILURE);
}
}
}
}
int main() {
startup("User:DESKTOP$ ");
std::cin.get();
}
You can use std::getline to keep reading in strings up to a newline:
while(std::getline(std::cin, input_t))
{
if (line.empty())
{
std::cout << start;
continue;
}
// else do stuff with input_t, or break
}

std::cin is not blocking when process is forked

I have a C++ console application which forks itself and closes the main process.
std::cin in the childprocess is not blocking anymore if a press any key. This results in an endless loop. If I don't fork before then the application behaves as expected.
I have tried different combinations of cin::ignore, cin::fail, cin::clear and close to get this fixed but without success.
I'm using Ubuntu 18.04.
Why this is happening and how can I fix that?
/* includes */
#include <iostream>
#include <unistd.h>
#include <limits>
void fork_to_background()
{
pid_t f_return = fork();
if (f_return == -1)
{
exit(1);
}
if (f_return != 0)
{
exit(0);
}
}
int main(int argc, char** argv)
{
fork_to_background();
std::string commands;
while(true)
{
std::cin >> commands;
std::cout << "Loop" << std::endl;
//std::cin.clear();
//std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
}
std::cin >> commands; does not block when you reach EOF, you can see it checking if >> success, for instance
if (! std::cin >> commands) {
std::cout << "EOF" << std::endl;
break;
}
the two lines you put in comment are useless here because you read a string, they are useful in case you read for instance a number and the input is not a valid number
note the parent process exit immediately after the fork, closing stdin for the child because they share stdin
if I modify your program to have :
/* includes */
#include <stdlib.h>
#include <iostream>
#include <unistd.h>
#include <limits>
#include <sys/wait.h>
void fork_to_background()
{
pid_t f_return = fork();
if (f_return == -1)
{
exit(1);
}
if (f_return != 0)
{
waitpid(f_return, NULL, 0); // wait end of child
exit(0);
}
}
int main(int argc, char** argv)
{
fork_to_background();
std::string commands;
while(std::cin >> commands)
{
std::cout << commands << std::endl;
std::cout << "Loop" << std::endl;
}
std::cout << "done" << std::endl;
}
Compilation and execution :
/tmp % g++ -Wall f.cc
/tmp % echo "aze qsd" | ./a.out
aze
Loop
qsd
Loop
done
/tmp %

How to wait for a specific keystroke?

I'm a bit new to C++, so I beg your pardon for being a bit nooby.
Is there a function I can use to make the console pause until a specific key is pressed?
Example being:
#include <iostream>
using namespace std;
int main()
{
int i = 0;
if (specific key pressed) {
i = 1;
} else if (other key pressed) {
i = 2;
}
cout << i << endl;
return 0;
}
The console should output 1 if the right key is pressed, and 2 if another key is.
What you're trying to do is a bit more complex, C++ makes use of the cin stream where the input into the console is fed into your program. Where as a key-press event would be something the operating system would handle and would vary between operating systems. So using something like this would require the user to press enter/return for the input to be received by the program.
char key;
std::cin >> key;
if (key == 'a') {
std::cout << 1;
}
else {
std::cout << 2;
}
Find some answers here How to handle key press events in c++
Works on Windows only:
#include <iostream>
#include <vector>
#include <Windows.h>
char GetKey(std::vector<char> KeysToCheckFor)
{
while (true)
{
Sleep(1);
for (int i = 0; i < KeysToCheckFor.size(); i++)
{
if (GetKeyState(toupper(KeysToCheckFor[i])) < 0) { return KeysToCheckFor[i]; }
}
}
}
int main()
{
std::cout << "Press one of the keys: a,b,c\n";
char returnedkey = GetKey({ 'a', 'b', 'c' });
std::cout << returnedkey << " has been pressed!\n";
system("pause");
}

How to skip cin on purpose in C++?

I need to have a while-loop running and accept input to it whenever there is an input. I'm not new to C++, but this hurdle is quite difficult. Due to an NDA (this school project is apparently some secret stuff) I can only show you the test case.
I've been grasping for straws trying to solve the problem; try catch, cin.get, cin.peek, if(cin.peek){}. If anybody can point me in the right direction I would be very grateful!
The program is not time-critical, but a function needs to be called with a fixed interval. It is not essential that the code is portable, that it is a while-cin-combination or anything like that; the code will only ever run on a Windows 7 or Windows 8 PC with at least dual core processor.
#include <iostream>
#include <ctime>
using namespace std;
int main()
{
int input = 0;
int pastTime, nowTime;
pastTime = nowTime = time(0);
cin >> input;
while(input != -1)
{
if(input == 1)
{
cout << "Entered 1" << endl;
//To be done instead of the two 'elses',
//bypassing interval-dependant code
}
else if(input == 2)
{
cout << "Entered 2" << endl;
//To be done instead of the interval-dependant code
}
else if(pastTime == (nowTime - 5))
{
cout << "Nothing entered." << endl;
//Needs to be done with a fixed interval.
}
nowTime = time(0);
cin >> input;
}
return 0;
}
The solution was, based om James Beilby's link:
// This program is based on counter.cpp from Boost\lib\thread\tutorial
#include <boost/thread/thread.hpp>
#include <iostream>
#include <ctime>
int timeNow = time(0);
int timePast = time(0);
void fct_one()
{
while(1) //keeps running all the time
{
if(timePast == (timeNow - 3)) // only executed once every three seconds
{
//do some stuff
timePast = time(0);
}
timeNow = time(0); // time is continuously updated
}
}
void fct_two()
{
int input = 0;
int timeTemp = time(0);
while(1) //keeps running all the time
{
std::cin >> input; // cin blocking for input
if(input == 1)
{
//do some stuff
}
if(input == 2)
{
//do some stuff
}
if(input == -1)
{
std::cout << "Program is done. ";
system("pause");
exit(1);
}
}
}
int main()
{
boost::thread_group threads;
threads.create_thread(&fct_one)
threads.create_thread(&fct_two);
threads.join_all();
return 0;
}
I would completely separate reading input from cin and performing the default timeout function. You'll need something like a background thread that performs the default function based on the time interval. To handle the 1st two cases you'll need to signal the thread skipping the next execution (if this is really necessary), and just call any function you want or do nothing.
The simple answer is to put the code that runs at some interval on another thread. Since you've noted this is Windows, you could use a Timer Queue:
Begin with routines to start and stop your time dependent work:
HANDLE Start(HANDLE hTimerQueue)
{
DWORD timerMS = 5000; /* every 5 seconds */
HANDLE hTimer;
if (!CreateTimerQueueTimer(&hTimer,
hTimerQueue,
(WAITORTIMERCALLBACK)timerWork,
/*lpParam*/NULL,
/*start in ___ ms:*/0,
/*run every __ ms:*/timerMS,
/*flags*/0))
{
return NULL;
}
return hTimer;
}
BOOLEAN Stop(HANDLE hTimerQueue, HANDLE hTimer)
{
if (!DeleteTimerQueueTimer(hTimerQueue,
hTimer,
/*wait for our timer to complete*/INVALID_HANDLE_VALUE))
{
return FALSE;
}
return TRUE;
}
Then put your time dependent work into its own callback:
VOID CALLBACK timerWork(PVOID lpParam, BOOLEAN TimerOrWaitFired /*ignored*/)
{
for (int ii = 0; ii < 10; ++ii) {
std::cout << "timer work: " << ii << std::endl;
Sleep(250);
}
}
Finally, integrate these into your workflow:
int main(int argc, char* argv[])
{
HANDLE hTimerQueue = CreateTimerQueue(hTimerQueue);
if (NULL == hTimerQueue) return -1;
HANDLE hTimer = Start(hTimerQueue);
if (NULL == hTimer) return -1;
/* our timed callback is now running in the background */
int input = 0;
std::cin >> input;
while(input != -1)
{
if(input == 1)
{
if (Stop(hTimerQueue, hTimer)) {
std::cout << "Entered 1" << std::endl;
if (NULL == (hTimer = Start(hTimerQueue))) return -2;
}
}
else if(input == 2)
{
if (Stop(hTimerQueue, hTimer)) {
std::cout << "Entered 2" << std::endl;
if (NULL == (hTimer = Start(hTimerQueue))) return -2;
}
}
std::cin >> input;
}
DeleteTimerQueue(hTimerQueue);
return 0;
}

Non-blocking console input C++

I'm looking for a (multiplatform) way to do non-blocking console input for my C++ program, so I can handle user commands while the program continually runs. The program will also be outputting information at the same time.
What's the best/easiest way to do this? I have no problem using external libraries like boost, as long as they use a permissive license.
Example using C++11:
#include <iostream>
#include <future>
#include <thread>
#include <chrono>
static std::string getAnswer()
{
std::string answer;
std::cin >> answer;
return answer;
}
int main()
{
std::chrono::seconds timeout(5);
std::cout << "Do you even lift?" << std::endl << std::flush;
std::string answer = "maybe"; //default to maybe
std::future<std::string> future = std::async(getAnswer);
if (future.wait_for(timeout) == std::future_status::ready)
answer = future.get();
std::cout << "the answer was: " << answer << std::endl;
exit(0);
}
online compiler: https://rextester.com/GLAZ31262
I would do this by creating separate a thread which calls normal blocking IO functions and pass it a callback function which it would call when it got input. Are you sure you need to do what you said you want to do?
As for outputting information at the same time, what would happen if the user was in the middle of typing some input and you printed something?
I've done this on QNX4.5 that doesn't support threads or Boost by using select. You basically pass select STDIN as the file descriptor to use and select will return when a new line is entered. I've added a simplified example loop below. It's platform independent, at least for Unix like systems. Not sure about Windows though.
while (!g_quit)
{
//we want to receive data from stdin so add these file
//descriptors to the file descriptor set. These also have to be reset
//within the loop since select modifies the sets.
FD_ZERO(&read_fds);
FD_SET(STDIN_FILENO, &read_fds);
result = select(sfd + 1, &read_fds, NULL, NULL, NULL);
if (result == -1 && errno != EINTR)
{
cerr << "Error in select: " << strerror(errno) << "\n";
break;
}
else if (result == -1 && errno == EINTR)
{
//we've received and interrupt - handle this
....
}
else
{
if (FD_ISSET(STDIN_FILENO, &read_fds))
{
process_cmd(sfd);
}
}
}
There is one easy way:
char buffer[512];
int point = 0;
...
while (_kbhit()) {
char cur = _getch();
if (point > 511) point = 511;
std::cout << cur;
if (cur != 13) buffer[point++] = cur;
else{
buffer[point] = '\0';
point = 0;
//Run(buffer);
}
}
No block, all in 1 thread. As for me, this works.
Non-blocking console input C++ ?
Ans: do console IO on a background thread and provide a means of communicating between threads.
Here's a complete (but simplistic) test program that implements async io by deferring the io to a background thread.
the program will wait for you to enter strings (terminate with newline) on the console and then perform a 10-second operation with that string.
you can enter another string while the operation is in progress.
enter 'quit' to get the program to stop on the next cycle.
#include <iostream>
#include <memory>
#include <string>
#include <future>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <deque>
int main()
{
std::mutex m;
std::condition_variable cv;
std::string new_string;
bool error = false;
auto io_thread = std::thread([&]{
std::string s;
while(!error && std::getline(std::cin, s, '\n'))
{
auto lock = std::unique_lock<std::mutex>(m);
new_string = std::move(s);
if (new_string == "quit") {
error = true;
}
lock.unlock();
cv.notify_all();
}
auto lock = std::unique_lock<std::mutex>(m);
error = true;
lock.unlock();
cv.notify_all();
});
auto current_string = std::string();
for ( ;; )
{
auto lock = std::unique_lock<std::mutex>(m);
cv.wait(lock, [&] { return error || (current_string != new_string); });
if (error)
{
break;
}
current_string = new_string;
lock.unlock();
// now use the string that arrived from our non-blocking stream
std::cout << "new string: " << current_string;
std::cout.flush();
for (int i = 0 ; i < 10 ; ++i) {
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << " " << i;
std::cout.flush();
}
std::cout << ". done. next?\n";
std::cout.flush();
}
io_thread.join();
return 0;
}
sample test run:
$ ./async.cpp
first
new string: first 0 1las 2t 3
4 5 6 7 8 9. done. next?
new string: last 0 1 2 3 4 5 6 7 8quit 9. done. next?
ncurses can be a good candidate.
The StdinDataIO class of the BSD-licensed MUSCLE networking library supports non-blocking reads from stdin under Windows, MacOS/X, and Linux/Unix ... you could use that (or just examine the code as an example of how it can be done) if you want.
You can use the tinycon library to do this. Just spawn a tinycon object in a new thread, and you are pretty much done. You can define the trigger method to fire off whatever you'd like when enter is pressed.
You can find it here:
https://sourceforge.net/projects/tinycon/
Also, the license is BSD, so it will be the most permissive for your needs.
libuv is a cross-platform C library for asynchronous I/O. It uses an event loop to do things like read from standard input without blocking the thread. libuv is what powers Node.JS and others.
In a sense, this answer is incomplete. But yet, I think it can be useful even for people who have different platforms or circumstances, giving the idea, what to look for in their platform.
As I just wrote some scripting engine integration into an SDL2 main event loop (which is supposed to read lines from stdin if there are lines to be read), here is how I did it (on linux (debian bullseye 64 bit)). See below.
But even if you are not on linux, but on some other posix system, you can use the equivalent platform APIs of your platform. For example, you can use kqueue on FreeBSD. Or you can consider using libevent for a bit more portable approach (still will not really work on Windows).
This approach might also work on Windows if you do some special fiddling with the rather new-ish ConPTY. In traditional windows console applications, the problem is, that stdin is not a real file handle and as such, passing it to libevent or using IOCP (IO completion ports) on it will not work as expected.
But, this approach should also work on posix systems, if there is redirection at play. As long as there is a file handle available.
So how does it work?
Use epoll_wait() to detect if there is data available on stdin. While consoles can be configured in all sorts of ways, typically, they operate on a line by line basis (should also apply for ssh etc.).
Use your favorite getline() function to read the line from stdin. Which will work, because you know, there is data and it will not block (unless your console is not defaulting to line by line handling).
Rince and repeat.
#include <unistd.h>
#include <sys/epoll.h>
#include <iostream>
#include <string>
#include <array>
using EpollEvent_t = struct epoll_event;
int main(int argc, const char* argv[]) {
//
// create epoll instance
//
int epollfd = epoll_create1(0);
if (epollfd < 0) {
std::cout << "epoll_create1(0) failed!" << std::endl;
return -1;
}
//
// associate stdin with epoll
//
EpollEvent_t ev;
ev.data.ptr = nullptr;
ev.data.fd = STDIN_FILENO; // from unistd.h
ev.data.u32 = UINT32_C(0);
ev.data.u64 = UINT64_C(0);
ev.events = EPOLLIN;
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, STDIN_FILENO, &ev) < 0) {
std::cout
<< "epoll_ctl(epollfd, EPOLL_CTL_ADD, fdin, &ev) failed."
<< std::endl;
return -1;
}
//
// do non-blocking line processing in your free running
// main loop
//
std::array<EpollEvent_t,1> events;
bool running = true;
while (running) {
int waitret = epoll_wait(epollfd,
events.data(),
events.size(),
0); // 0 is the "timeout" we want
if (waitret < 0) {
std::cout << "epoll_wait() failed." << std::endl;
running = false;
}
if (0 < waitret) { // there is data on stdin!
std::string line;
std::getline(std::cin, line);
std::cout
<< "line read: [" << line << "]" << std::endl;
if (line == "quit")
running = false;
}
// ... Do what you usually do in your main loop ...
}
//
// cleanup of epoll etc.
//
close(epollfd);
return 0;
}
You could do:
#include <thread>
#include <chrono>
#include <string>
#include <iostream>
int main() {
std::cout << "Type exit to quit." << std::endl;
// initialize other std::thread handlers here
std::string input;
while (input != "exit") {
std::getline(std::cin, input);
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
std::cout << "Cleaning up and quitting" << std::endl;
return 0;
};
A simple answer with thread/future and reading a single char at a time (you can replace getchar with cin as required)
Timeout is set to zero and a new future is created every time the previous call is completed.
Like cin, getchar requires that the user hits the RETURN key to end the function call.
#include <chrono>
#include <cstdio>
#include <future>
#include <iostream>
#include <thread>
static char get_usr_in()
{
return std::getchar();
}
int main()
{
std::chrono::seconds timeout(0);
std::future<char> future = std::async(std::launch::async, get_usr_in);
char ch = '!';
while(ch!='q') {
if(future.wait_for(timeout) == std::future_status::ready) {
ch = future.get();
if(ch!='q') {
future = std::async(std::launch::async, get_usr_in);
}
if(ch >= '!' && ch <'~')
std::cout << "ch:" << ch << std::endl;
}
std::cout << "." << std::endl;
}
exit(0);
}
Why not use promises?
#include <iostream>
#include <istream>
#include <thread>
#include <future>
#include <chrono>
void UIThread(std::chrono::duration<int> timeout) {
std::promise<bool> p;
std::thread uiWorker([&p]() {
bool running = true;
while(running) {
std::string input;
std::cin >> input;
if(input == "quit") {
p.set_value(true);
running = false;
}
}
});
auto future = p.get_future();
if (future.wait_for(timeout) != std::future_status::ready) {
std::cout << "UI thread timed out" << std::endl;
uiWorker.detach();
return;
}
uiWorker.join();
}
int main()
{
std::thread uiThread(UIThread, std::chrono::seconds(3));
std::cout << "Waiting for UI thread to complete" << std::endl;
uiThread.join();
}
online complier