Interrupt a getLine() while loop in C++ - c++

I made a console applications that accepts commands from two sources:
The actual console -> this is a while(getLine()) loop in a seperate thread.
A websocket server -> this also runs on a seperate thread
If there is a command entered, the command is stored in a vector until another while loop (that runs every 20ms) loops trough all the commands entered in the time passed. If he reads a command, he executes it.
Now, there is a Stop command who stops the application. When entered, the application shuts down as expected. But the problem is: this takes some time, and you can still enter text from the first command source (getline()). Once you type something, the shutdown sequence stops, and waits until you pressed enter.
I terminate the first thread (that contains the getline loop) once the shutdown sequence starts. But that doesn't work...
Any ideas?
Thanks in advance!

getline() is a blocking call, you'll probably have to use something different, if you want to receive messages (i.e. a shut down command) from other threads. You did not mention which library you use for multithreading and how you terminate the console reading thread (it's possible, that your way of stopping the thread still does not force it to exit from getline)
This question seems to have some relevant answers: Peek stdin using pthreads
By the way, you mentioned a vector, which is (if I understood it correctly) accessed from multiple threads. You'll have to take care about proper synchronization (e.g. using a mutex when accessing the vector).
Also, the fact that you have some kind of loop, which "polls" the vector every 20 ms is indicating that you may have some flaws in overall design of your application. Try to get rid of it by using more appropriate means for passing events between threads, such as condition variables.

The problem is that getline is a blocking call and will return just after you press ENTER in case of stdin.
I had a similar problem and solved it as shown below.
I used two file descriptors: one to monitor the stdin and an other to monitor a "self-pipe". The latter acts as a trigger to unlock the select in case some event happens. The former ensures getline is called just once it can read a full line.
#include <future>
#include <string>
#include <iostream>
#include <thread>
#include <unistd.h>
#include <stdio.h>
#include <sys/select.h>
int pipe_fd[2];
auto p = pipe(pipe_fd);
auto stdin_fd = fileno(stdin); // 0
fd_set check_fd;
int main(int argc, char const *argv[])
{
FD_ZERO(&check_fd);
FD_SET(stdin_fd, &check_fd);
FD_SET(pipe_fd[0], &check_fd);
auto t1 = std::async(std::launch::async, [] {
std::this_thread::sleep_for(std::chrono::seconds(10));
uint32_t dummy = 43;
// this will stop the data input
write(pipe_fd[1], &dummy, sizeof(dummy));
});
auto maxfd = pipe_fd[0] > pipe_fd[1] ? pipe_fd[0] : pipe_fd[1];
select(maxfd + 1, &check_fd, nullptr, nullptr, nullptr);
if (FD_ISSET(stdin_fd, &check_fd))
{
std::string input;
std::getline(std::cin, input);
std::cout << "You enterd:" << input << std::endl;
}
if (FD_ISSET(pipe_fd[0], &check_fd))
std::cout << "Event" << std::endl;
return 0;
}

Related

Is there any method to abort cin or scanf

I have a multithreaded program in which on thread waits for input through a terminal and the other will get data from the socket. Is there any way to abort first threads cin/scanf to print in console data from second thread.
I think to kill the first thread, print data from second thread then run first thread again. But I'm looking for a better method, something like abort cin then reawoke it.
void thread1(){
cin>>string;
doSomething();
}
void thread2(){
cout<<getSomeData();
}
In usual case, it won't print data till something would be entered from keyboard.
[EDIT]
I found a particular solution, like if it doesn't get input it will interrupt, everything was done in C style.
In any case if you are interested check "Head First C" book, section "Interprocess Communication: It's good to talk".
I know it's bit too late. After a while I was supposed to make cpp multithreaded application again and had the same problem. This time it was done with implementing non blocking input with stdio`s getch() and I think it fits to be the best solution.
I don't know if the following solution is standard enough, but it works on both my Fedora Linux (GCC 10.3) & Windows 10 (MSVC 16.11)
#include <iostream>
#include <csignal>
int main()
{
std::signal(SIGINT, [] (int s)
{
std::signal(s, SIG_DFL);
std::fclose(stdin);
std::cin.setstate(std::ios::badbit); // To differenciate from EOF input
});
std::string input;
std::cout << "Input CTRL+C or EOF now!" << std::endl;
std::getline(std::cin, input);
std::cout << (std::cin.bad() ? "\rinterrupted" : "eof") << std::endl;
}
Don't ask me how to reuse cin from that state now.

How to prevent input text breaking while other thread is outputting to the console?

I have 2 threads: one of them is constantly cout'ing to the console some value, let's say increments an int value every second - so every second on the console is 1,2,3... and so on.
Another thread is waiting for user input - with the command cin.
Here is my problem: when I start typing something, when the time comes to cout the int value, my input gets erased from the input field, and put into the console with the int value. So when I want to type in "hello" it looks something like this:
1
2
3
he4
l5
lo6
7
8
Is there a way to prevent my input from getting put to the console, while other thread is writing to the console?
FYI this is needed for a chat app at client side - one thread is listening for messages and outputs this message as soon as it comes in, and the other thread is listening for user input to be sent to a server app.
Usually the terminal itself echos the keys typed. You can turn this off and get your program to echo it. This question will give you pointers on how to do it Hide password input on terminal
You can then just get the one thread to handle output.
If you are a slow typer, then the solution to your problem can be, as I said, making it a single thread, but that may make the app to receive only after it sends.
Another way is to increase your receiving thread's sleep time, which would provide you some more time to type (without interruption)
You could make a GUI (or use ncurses if you really want to work in the console). This way you avoid having std::cout shared by the threads.
I think you could solve this problem with a semaphore. When you have an incoming message you check to see if the user is writing something. If he does you wait until he finishes to print the message.
Is there a way to prevent my input from getting put to the console, while other thread is writing to the console?
It is the other way around. The other thread shouldn't interrupt the display of what you are typing.
Say you have typed "Hel" and then a new message comes in from the other thread. What do you do? How should it be displayed?
Totally disable echoing of what you type and only display it after you hit enter. In this way you can display messages from the different threads properly, in an atomic fashion. The big drawback is that you cannot see what you have typed already... :(
You immediately echo what you type. When the new message comes in, you undo the "Hel", print the new message and print again "Hel" on a new line and you can continue typing. Doable but a bit ugly.
You echo what you type in a separate place. That is, you split somehow the display. In one place you display the posted/received messages in order; and in another place you display what you are typing. You either need a GUI or at least some console library to do this. This would be the nicest solution but perhaps the most difficult to port to another OS due to the library dependencies.
In any case, you need a (preferably internally) synchronized stream that you can safely call from different threads and can write strings into it atomically. That is, you need to write your own synchronized stream class.
Hope this helps.
Well i recently solved this same issue with a basic workaround. This might not be the #1 solution but worked like a charm for me, as a newbie;
#include <iostream> // I/O
#include <Windows.h> // Sleep();
#include <conio.h> // _getch();
#include <string> // MessageBuffer
#include <thread> // Thread
using namespace std;
void ThreadedOutput();
string MessageBuffer; // or make it static
void main()
{
thread output(ThreadedOutput); // Attach the output thread
int count = 0;
char cur = 'a'; // Temporary at start
while (cur != '\r')
{
cur = _getch(); // Take 1 input
if (cur >= 32 && cur <= 126) // Check if input lies in alphanumeric and special keys
{
MessageBuffer += cur; // Store input in buffer
cout << cur; // Output the value user entered
count++;
}
else if (cur == 8) // If input key was backspace
{
cout << "\b \b"; // Move cursor 1 step back, overwrite previous character with space, move cursor 1 step back
MessageBuffer = MessageBuffer.substr(0, MessageBuffer.size() - 1); // Remove last character from buffer
count--;
}
else if (cur == 13) // If input was 'return' key
{
for (int i = 0; i < (signed)MessageBuffer.length(); i++) // Remove the written input
cout << "\b \b";
// "MessageBuffer" has your input, use it somewhere
MessageBuffer = ""; // Clear the buffer
}
}
output.join(); // Join the thread
}
void ThreadedOutput()
{
int i = 0;
while (true)
{
for (int i = 0; i < (signed)MessageBuffer.length(); i++) // Remove the written input
cout << "\b \b";
cout << ++i << endl; // Give parallel output with input
cout << MessageBuffer; // Rewrite the stored buffer
Sleep(1000); // Prevent this example spam
}
}

Send data to another C++ program

Is it possible to send data to another C++ program, without being able to modify the other program (since a few people seem to be missing this important restriction)? If so, how would you do it? My current method involves creating a temporary file and starting the other program with the filename as a parameter. The only problem is that this leaves a bunch of temporary files laying around to clean up later, which is not wanted.
Edit: Also, boost is not an option.
Clearly, building a pipe to stdin is the way to go, if the 2nd program supports it. As Fred mentioned in a comment, many programs read stdin if either there is no named file provided, or if - is used as the filename.
If it must take a filename, and you are using Linux, then try this: create a pipe, and pass /dev/fd/<fd-number> or /proc/self/fd/<fd-number> on the command line.
By way of example, here is hello-world 2.0:
#include <string>
#include <sstream>
#include <cstdlib>
#include <cstdio>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main () {
int pfd[2];
int rc;
if( pipe(pfd) < 0 ) {
perror("pipe");
return 1;
}
switch(fork()) {
case -1: // Error
perror("fork");
return 1;
case 0: { // Child
// Close the writing end of the pipe
close(pfd[1]);
// Create a filename that refers to reading end of pipe
std::ostringstream path;
path << "/proc/self/fd/" << pfd[0];
// Invoke the subject program. "cat" will do nicely.
execlp("/bin/cat", "cat", path.str().c_str(), (char*)0);
// If we got here, then something went wrong, then execlp failed
perror("exec");
return 1;
}
default: // Parent
// Close the reading end.
close(pfd[0]);
// Write to the pipe. Since "cat" is on the other end, expect to
// see "Hello, world" on your screen.
if (write(pfd[1], "Hello, world\n", 13) != 13)
perror("write");
// Signal "cat" that we are done writing
close(pfd[1]);
// Wait for "cat" to finish its business
if( wait(0) < 0)
perror("wait");
// Everything's okay
return 0;
}
}
You could use sockets. It sounds like both application are on the same host, so you just identify the peers as localhost:portA and localhost:port B. And if you do it this way you can eventually graduate to do network IO. No temp files, no mystery parse errors or file deletions. TCP guarantees packet delivery and guarantees they will be ordered correctly.
So yeah, I would consider creating an synchronous socket server (use asynchronous if you anticipate having tons of peers). One benefit over pipe oriented IPC is that TCP sockets are completely universal. Piping varies dramatically based upon what system you are on (consider Windows named pipes vs implicit and explicit POSIX pipes -> very different).

Distinguish if program runs by clicking on the icon, typing its name in the console, or from a batch file

The program I am writing is a simple console application that gets params, computes, and then returns data.
I am asking this because I am trying to implement a smart "press enter to exit" message that would run only if a console program is called by clicking on its icon in explorer. Without it, the result is that program only flashes for a split of second, but if a program is run from a context of already opened console then the same thing becomes an annoyance. Similar thing arises when program is run inside bat or cmd file, then pausing at the end is also unwelcome since bat files have 'pause' command that is supposed to do it.
So, we have 2 modes:
program says "press enter to exit" when is started by:
direct clicking in explorer
clicking on a shortcut
Simply exit when:
its name is typed in console
it is run from a bat/cmd file
it is run from another console application
Using Windows APIs:
You can use the GetConsoleProcessList API function (available on Windows XP/2003 and higher only). It returns a list of processes that are attached to the current console. When your program is launched in the "no console" mode, your program is the only process attached to the current console. When your program is launched from another process which already has a console, there will be more than one process attached to the current console.
In this case, we don't care about the list of process IDs returned by the function, we only care about the count that is returned.
Example program (I used Visual C++ with a Console Application template):
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
DWORD procIDs[2];
DWORD maxCount = 2;
DWORD result = GetConsoleProcessList((LPDWORD)procIDs, maxCount);
cout << "Number of processes listed: " << result << endl;
if (result == 1)
{
system("pause");
}
return 0;
}
We only need to list up to 2 processes, because we only care whether there is 1 or more than 1.
Using Windows APIs present in Windows 2000:
GetConsoleWindow returns the window handle of the console associated with the current process (if any). GetWindowThreadProcessId can tell you which process created a window. And finally, GetCurrentProcessId tells you the id of current process. You can make some useful deductions based on this information:
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
HWND consoleWindow = GetConsoleWindow();
if (consoleWindow != NULL)
{
DWORD windowCreatorProcessId;
GetWindowThreadProcessId(consoleWindow, &windowCreatorProcessId);
if (windowCreatorProcessId == GetCurrentProcessId())
{
cout << "Console window was created by this process." << endl;
system("pause");
}
else
cout << "Console window was not created by this process." << endl;
}
else
cout << "No console window is associated with this process." << endl;
return 0;
}
This technique seems slightly less precise than the first one, but I think in practice it should perform equally well.
The simplest solution I can think of is require the first parameter to be a flag whether or not the program should pause at the end. If the parameter is not there, i.e. it was started via explorer and the user did not have the ability to pass it in, then it should pause.
//Pseudo-code!!
int main(int argc, char** argv) {
//...
if(argv[1] == SHOULD_PAUSE) system("pause");
return 0;
}
There's a simple way to do this, and of course a more complicated way. The more complicated way may be more fun in the end, but probably more trouble than it's worth.
For the simple way, add a command line argument to the program, --pause-on-exit or something similar. Pass the extra arg whan calling it from a batch-file or the launcher icon. You could of course rather check for an environment variable for a similar effect.
For a more complicated (and automatic) way, you could probably try to find out who is the parent process of your application. You may have to go further up the chain than your immediate parent, and it may not work in all cases. I'd go for the command line argument.
Elaborating on my comment, rather than trying to tell how the program was executed (which I don't know is even possible, I'd assume there's no difference/distinction at all), I would implement a similar functionality in either one of two ways:
Add an extra argument to the program that will either make it "pause" at the end before terminating or not. ie. You could have something like -w to make it wait, or -W to make it not wait, and default with not waiting (or vice versa). You can add arguments through shortcuts.
Add a timer at the end of the program so that you wait for a few seconds, long enough for the user to read the input, so that the program doesn't wait infinitely when used in a batch.
Visual Studio introduces a wrinkle to #tcovo's otherwise valid answer when you are debugging. In this situation, it creates a second process and attaches it to the same console as the process you're running in:
So, it's necessary to detect the debugger using the Windows API function IsDebuggerPresent in order to get a definitive answer:
#include <iostream>
#include <Windows.h>
#include "debugapi.h"
int main()
{
DWORD pl[2];
auto np = GetConsoleProcessList(pl, 2);
std::cout << np << " processes\n";
bool shared;
if (IsDebuggerPresent())
shared = np > 2;
else
shared = np > 1;
std::cout << "Shared: ";
std::boolalpha(std::cout);
std::cout << shared << "\n";
std::cin.ignore(1);
return 0;
}
This only matters if you're using the local debugger; when run in a remote debugger there is still only one process attached.

Is there a decent wait function in C++?

One of the first things I learned in C++ was that
#include <iostream>
int main()
{
std::cout<<"Hello, World!\n";
return 0;
}
would simply appear and disappear extremely quickly without pause. To prevent this, I had to go to notepad, and save
helloworld.exe
pause
ase
helloworld.bat
This got tedious when I needed to create a bunch of small test programs, and eventually I simply put while(true); at the end on most of my test programs, just so I could see the results. Is there a better wait function I can use?
you can require the user to hit enter before closing the program... something like this works.
#include <iostream>
int main()
{
std::cout << "Hello, World\n";
std::cin.ignore();
return 0;
}
The cin reads in user input, and the .ignore() function of cin tells the program to just ignore the input. The program will continue once the user hits enter.
Link
Please note that the code above was tested on Code::Blocks 12.11 and Visual Studio 2012
on Windows 7.
For forcing your programme stop or wait, you have several options :
sleep(unsigned int)
The value has to be a positive integer in millisecond.
That means that if you want your programme wait for 2 seconds, enter 2000.
Here's an example :
#include <iostream> //for using cout
#include <stdlib.h> //for using the function sleep
using namespace std; //for using cout
int main(void)
{
cout << "test" << endl;
sleep(5000); //make the programme waiting for 5 seconds
cout << "test" << endl;
sleep(2000); // wait for 2 seconds before closing
return 0;
}
If you wait too long, that probably means the parameter is in seconds. So change it to this:
sleep(5);
For those who get error message or problem using sleep try to replace it by _sleep or Sleep especially on Code::Bloks.
And if you still getting problems, try to add of one this library on the beginning of the code.
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <dos.h>
#include <windows.h>
system("PAUSE")
A simple "Hello world" programme on windows console application would probably close before you can see anything. That the case where you can use system("Pause").
#include <iostream>
using namespace std;
int main(void)
{
cout << "Hello world!" << endl;
system("PAUSE");
return 0;
}
If you get the message "error: 'system' was not declared in this scope" just add
the following line at the biggining of the code :
#include <cstdlib>
cin.ignore()
The same result can be reached by using cin.ignore() :
#include <iostream>
using namespace std;
int main(void)
{
cout << "Hello world!" << endl;
cin.ignore();
return 0;
}
cin.get()
example :
#include <iostream>
using namespace std;
int main(void)
{
cout << "Hello world!" << endl;
cin.get();
return 0;
}
getch()
Just don't forget to add the library conio.h :
#include <iostream>
#include <conio.h> //for using the function getch()
using namespace std;
int main(void)
{
cout << "Hello world!" << endl;
getch();
return 0;
}
You can have message telling you to use _getch() insted of getch
Lots of people have suggested POSIX sleep, Windows Sleep, Windows system("pause"), C++ cin.get()… there's even a DOS getch() in there, from roughly the late 1920s.
Please don't do any of these.
None of these solutions would pass code review in my team. That means, if you submitted this code for inclusion in our products, your commit would be blocked and you would be told to go and find another solution. (One might argue that things aren't so serious when you're just a hobbyist playing around, but I propose that developing good habits in your pet projects is what will make you a valued professional in a business organisation, and keep you hired.)
Keeping the console window open so you can read the output of your program is not the responsibility of your program! When you add a wait/sleep/block to the end of your program, you are violating the single responsibility principle, creating a massive abstraction leak, and obliterating the re-usability/chainability of your program. It no longer takes input and gives output — it blocks for transient usage reasons. This is very non-good.
Instead, you should configure your environment to keep the prompt open after your program has finished its work. Your Batch script wrapper is a good approach! I can see how it would be annoying to have to keep manually updating, and you can't invoke it from your IDE. You could make the script take the path to the program to execute as a parameter, and configure your IDE to invoke it instead of your program directly.
An interim, quick-start approach would be to change your IDE's run command from cmd.exe <myprogram> or <myprogram>, to cmd.exe /K <myprogram>. The /K switch to cmd.exe makes the prompt stay open after the program at the given path has terminated. This is going to be slightly more annoying than your Batch script solution, because now you have to type exit or click on the red 'X' when you're done reading your program's output, rather than just smacking the space bar.
I assume usage of an IDE, because otherwise you're already invoking from a command prompt, and this would not be a problem in the first place. Furthermore, I assume the use of Windows (based on detail given in the question), but this answer applies to any platform… which is, incidentally, half the point.
The appearance and disappearance of a window for displaying text is a feature of how you are running the program, not of C++.
Run in a persistent command line environment, or include windowing support in your program, or use sleep or wait on input as shown in other answers.
the equivalent to the batch program would be
#include<iostream>
int main()
{
std::cout<<"Hello, World!\n";
std::cin.get();
return 0;
}
The additional line does exactly what PAUSE does, waits for a single character input
There is a C++11 way of doing it. It is quite simple, and I believe it is portable. Of course, as Lightness Races in Orbit pointed out, you should not do this in order to be able to see an Hello World in your terminal, but there exist some good reason to use a wait function. Without further ado,
#include <chrono> // std::chrono::microseconds
#include <thread> // std::this_thread::sleep_for
std::this_thread::sleep_for(std::chrono::microseconds{});
More details are available here. See also sleep_until.
Actually, contrary to the other answers, I believe that OP's solution is the one that is most elegant.
Here's what you gain by using an external .bat wrapper:
The application obviously waits for user input, so it already does what you want.
You don't clutter the code with awkward calls. Who should wait? main()?
You don't need to deal with cross platform issues - see how many people suggested system("pause") here.
Without this, to test your executable in automatic way in black box testing model, you need to simulate the enter keypress (unless you do things mentioned in the footnote).
Perhaps most importantly - should any user want to run your application through terminal (cmd.exe on Windows platform), they don't want to wait, since they'll see the output anyway. With the .bat wrapper technique, they can decide whether to run the .bat (or .sh) wrapper, or run the executable directly.
Focusing on the last two points - with any other technique, I'd expect the program to offer at least --no-wait switch so that I, as the user, can use the application with all sort of operations such as piping the output, chaining it with other programs etc. These are part of normal CLI workflow, and adding waiting at the end when you're already inside a terminal just gets in the way and destroys user experience.
For these reasons, IMO .bat solution is the nicest here.
What you have can be written easier.
Instead of:
#include<iostream>
int main()
{
std::cout<<"Hello, World!\n";
return 0;
}
write
#include<iostream>
int main()
{
std::cout<<"Hello, World!\n";
system("PAUSE");
return 0;
}
The system function executes anything you give it as if it was written in the command prompt. It suspends execution of your program while the command is executing so you can do anything with it, you can even compile programs from your cpp program.
Syntax:
void sleep(unsigned seconds);
sleep() suspends execution for an interval (seconds).
With a call to sleep, the current program is suspended from execution for the number of seconds specified by the argument seconds. The interval is accurate only to the nearest hundredth of a second or to the accuracy of the operating system clock, whichever is less accurate.
This example should make it clear:
#include <dos.h>
#include <stdio.h>
#include <conio.h>
int main()
{
printf("Message 1\n");
sleep(2); //Parameter in sleep is in seconds
printf("Message 2 a two seconds after Message 1");
return 0;
}
Remember you have to #include dos.h
EDIT:
You could also use winAPI.
VOID WINAPI Sleep(
DWORD dwMilliseconds
);
Sleep Function(Windows)
Just a note,the parameter in the function provided by winapi is in milliseconds ,so the sleep line at the code snippet above would look like this "Sleep(2000);"
getchar() provides a simplistic answer (waits for keyboard input).
Call Sleep(milliseconds) to sleep before exit.
Sleep function (MSDN)
You can use sleep() or usleep().
// Wait 5 seconds
sleep( 5 );
Well, this is an old post but I will just contribute to the question -- someone may find it useful later:
adding 'cin.get();' function just before the return of the main() seems to always stop the program from exiting before printing the results: see sample code below:
int main(){
string fname, lname;
//ask user to enter name first and last name
cout << "Please enter your first name: ";
cin >> fname;
cout << "Please enter your last name: ";
cin >> lname;
cout << "\n\n\n\nyour first name is: " << fname << "\nyour last name is: "
<< lname <<endl;
//stop program from exiting before printing results on the screen
cin.get();
return 0;
}
Before the return statement in you main, insert this code:
system("pause");
This will hold the console until you hit a key.
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s;
cout << "Please enter your first name followed by a newline\n";
cin >> s;
cout << "Hello, " << s << '\n';
system("pause");
return 0; // this return statement isn't necessary
}
The second thing to learn (one would argue that this should be the first) is the command line interface of your OS and compiler/linker flags and switches.