How to break the loop using user input? - c++

I am trying something like this.Its counting down seconds from 5-1.
#include<iostream>
#include<stdlib.h>
#include<windows.h>
#include<iomanip>
using namespace std;
int main()
{
for(int i=5;i>0;i--)
{
cout<<"\n\n\n\n\n\n";
cout<<setw(35);
cout<<i;
Sleep(1000);
system("CLS");
}
system("PAUSE");
}
And i trying to figure out a way to break the loop using a user input(from keyboard) to break it while its running. I have no idea about how to do this.I have heard about multi-threading. I don't even know if multi-threading has any application in my situation or not .So any ideas on how to break it in middle while its executing the loop?

I think you will need a thread to do it.
add a global variable in your main loop,
use a thread to receive the command line input and modify your global variable.
declare a global variable
bool stop = false;
create a thread to read stdin and modify 'stop'
DWORD WINAPI thread1(LPVOID pm)
{
//check the getchar value
int a = getchar();
while (a != '0'){
a = getchar();
}
stop = true;
return 0;
}
in your main:
HANDLE handle = CreateThread(NULL, 0, thread1, NULL, 0, NULL);
for(int i=5;i>0 && !stop;i--)
{
cout<<"\n\n\n\n\n\n";
cout<<setw(35);
cout<<i;
Sleep(1000);
system("CLS");
}

Try this:
#include<iostream>
using namespace std;
int main()
{
int i = 1;
while(i)
{
// do your work here
cin>>i;
}
cout<<"Terminated"<<endl;
}
Continue scanning int i, when you want to break loop give 0 as input value and your loop will be terminatd.

Related

Trying to make a scalable pipe and execvp program using loop

This program is trying to any number of commands greater than one and use pipes, execvp, and fork to chain them together much like a shell would. In this code I have a hard coded "ls" "wc" and "less" that should come out like running "ls | wc | less" on a shell. For some reason, the pipes are not working as intended. I have a big block of comments explaining what I think the problem is on line 99 (starting with "The read end of the..." ). I know there is no error checking, any help is appreciated.
#include <iostream>
#include <string.h>
#include <string>
#include <vector>
#include <sys/types.h>
#include <unistd.h>
using namespace std;
#define READ 0
#define WRITE 1
//This program will do three different commands ls, wc, then less.
int main(){
pid_t pid;
int cmd=3;
//One less pipe than command is required.
int fd[cmd-1][2];
//The pipes are created in a for loop.
for(int i=0; i<(cmd-1); i++){
if(pipe(fd[i])==-1){
cout<<"Help"<<endl;
}
}
//The commands are put in c.
char* c[3];
c[0]="ls";
c[1]="wc";
c[2]="less";
//First fork
pid=fork();
if(pid==0){
//Pipe 0 is linked up.
close(fd[0][READ]);
dup2(fd[0][WRITE], 1);
close(fd[0][WRITE]);
//Remaining pipes are closed.
for(int i=1; i<(cmd-1); i++){
close(fd[i][READ]);
close(fd[i][WRITE]);
}
//The command is prepared and then execvp is executed.
char* temp[2];
temp[0]=c[0];
temp[1]=NULL;
char* x=temp[0];
execvp(x, temp);
}
//This for loop executes two times less than the number of commands.
for(int i=0; i<(cmd-2); i++){
pid=fork();
if(pid==0){
//I link up the read connection with pipe 0, I am fairly certain that
//this part is working. You can put a cout after this pipe and it will
//print that of command 1.
close(fd[i][WRITE]);
dup2(fd[i][READ], 0);
close(fd[i][READ]);
//This is the linking of pipe 1.
close(fd[i+1][READ]);
dup2(fd[i+1][WRITE], 1);
close(fd[i+1][WRITE]);
//This closes the remaining pipes, in this case there are none.
for(int j=0; j<(cmd-1); j++){
if(j==i || j==(i+1)){
continue;
}
close(fd[j][READ]);
close(fd[j][WRITE]);
}
//The command is prepared and executed
char* temp[2];
temp[0]=c[i+1];
temp[1]=NULL;
char* x=temp[0];
execvp(x, temp);
}
}
pid=fork();
if(pid==0){
//The read end of the final pipe is linked here.
//THIS IS WERE THE PROBLEM IS! For some reason after dup2, I can no longer
//use cin. Inbetween the linking of pipe 0 and pipe 1 (line 66), I can
//use cin to make sure that the first execvp works and put its output in the
//pipe. I also know that the second execvp works as intended. I just need to
//know why dup2 messes up my program here.
close(fd[cmd-2][WRITE]);
dup2(fd[cmd-2][READ], 0);
close(fd[cmd-2][READ]);
//closes the remaining pipes.
for(int i=0; i<(cmd-2); i++){
close(fd[i][READ]);
close(fd[i][WRITE]);
}
//Preps next command.
char* temp[2];
temp[0]=c[cmd];
temp[1]=NULL;
char* x=temp[0];
execvp(x, temp);
//}
//closes all pipes.
for(int i=0; i<(cmd-1); i++){
close(fd[i][READ]);
close(fd[i][WRITE]);
}
return 0;
}
Your code has multiple problems
e.g. you've not allocated memory to commands and your code doesn't seem to be properly enclosed within brackets
I've modified your code as follows :
#include <iostream>
#include <string.h>
#include <string>
#include <vector>
#include <sys/types.h>
#include <unistd.h>
using namespace std;
//This program will do three different commands ls, wc, then less.
int main(){
pid_t pid = 0;
int cmd=3, i;
//One less pipe than command is required.
int fd[cmd-1][2];
//The pipes are created in a for loop.
for(int i=0; i<(cmd-1); i++){
if(pipe(fd[i])==-1){
cout<<"Help"<<endl;
}
}
//The commands are put in c.
char c[3][8] = {{'l', 's', '\0'}, {'w', 'c', '\0'}, {'l','e','s','s', '\0'}}, *temp[2];
for(i = 0; i < cmd-1; i ++){
pid = fork();
if(pid == 0){
if(i != 0){
// read from previous fd
close(fd[i-1][1]);
dup2(fd[i-1][0], STDIN_FILENO);
close(fd[i-1][0]);
}
// write to current fd
close(fd[i][0]);
dup2(fd[i][1], STDOUT_FILENO);
close(fd[i][1]);
temp[0] = c[i];
temp[1] = NULL;
execvp(c[i], temp);
exit(0);
}
else{
if(i != 0){
// close unnecessary fds in parent
close(fd[i-1][0]);
close(fd[i-1][1]);
}
}
}
// the last command i.e. less here
if(i > 0){
close(fd[i-1][1]);
dup2(fd[i-1][0], STDIN_FILENO);
close(fd[i-1][0]);
}
temp[0] = c[i];
temp[1] = NULL;
execvp(c[i], temp);
return 0;
}
Let me know if it works for you!

Run a thread to close the program when user press a specific key

I want to run a separate thread to close the program when user press a specific key. This is the structure of my program.
#include <iostream>
#include <windows.h>
using namespace std;
DWORD WINAPI foo(LPVOID lpParameter)
{
//do something
return 0;
}
DWORD WINAPI boo(LPVOID lpParameter)
{
//do something
return 0;
}
int main(int argc, char **argv)
{
HANDLE foo1,boo1;
while(true)
{
foo1 = CreateThread(NULL,0,foo,NULL,0,NULL);
boo1= CreateThread(NULL,0,boo,NULL,0,NULL);
//do something
}
return 0;
}
I have created two threads inside of always true while loop to keep the program running . So I want to add another thread to get user input whenever user press a key (while program is running) and after comparing it with specific already defined character, if they match close the program.
I have no idea of doing that.Can someone help me?
PS : I have to do that using threads only :)
You are not creating two threads. You are creating threads in an infinite loop until you run out of memory. Besides, your main is already running on a separate thread, so you can do your user input there. For example:
HANDLE hevent = NULL;
bool done = false;
DWORD WINAPI foo(LPVOID lpParameter)
{
while(!done)
{
::WaitForSingleObject(hevent, -1);
printf("\rfoo");
Sleep(1000);
::ResetEvent(hevent);
}
return 0;
}
DWORD WINAPI boo(LPVOID lpParameter)
{
while(!done)
{
printf("\rboo");
Sleep(1000);
SetEvent(hevent);
}
return 0;
}
int main(int argc, char **argv)
{
HANDLE foo1,boo1;
hevent = CreateEvent(NULL, TRUE, TRUE, NULL);
foo1 = CreateThread(NULL,0,foo,NULL,0,NULL);
boo1= CreateThread(NULL,0,boo,NULL,0,NULL);
HANDLE handles[] = {foo1, boo1};
char c = getchar();
done = true;
::WaitForMultipleObjects(2, handles, TRUE, -1);
return 0;
}

Error in breaking a loop during its execution

Hello I was trying to break the loop in middle of its execution.The loop shows a countdown of seconds from 5-1 .I want to break the loop in middle using any keystroke entered by the user.I researched for some time and created a thread. I set a global variable and updated it in the second thread. I gave a condition in the main function using that global variable but the loop doesn't break.
Here is the code.
Please help.
#include<iostream>
#include<windows.h>
#include<stdlib.h>
#include<iomanip>
#include<stdio.h>
using namespace std;
bool stop=false;
DWORD WINAPI thread1(LPVOID pm)
{
//check the getchar value
int a = getchar();
while (a != '0'){
a = getchar();
}
stop = true;
return 0;
}
int main()
{
HANDLE handle = CreateThread(NULL, 0, thread1, NULL, 0, NULL);
for(int i=5;i>0 && !stop;i--)
{
cout<<"\n\n\n\n\n\n";
cout<<setw(35);
cout<<i;
Sleep(1000);
system("CLS");
}
system("PAUSE");
}
The program counts down and in middle of the count down i tried to break the loop.thread1 function takes an input and modifies stop(global variable). But the loop in main function doesn't break(it should).Loop goes on decreasing loop variable, becomes zero and loop ends.
You have to declare stop as volatile
volatile bool stop
It informs compiler not optimized (by cache) access to variable, because another thread can modify it.
Also, take care about read and write access on global variable by many thread : in most of case, you have to protect them using mutex. (I think in your case it's not necessary according basic small type and basic access, but take care)
EDIT
As ask in comments, this is my design when inverting thread :
#include<iostream>
#include<windows.h>
#include<stdlib.h>
#include<iomanip>
#include<stdio.h>
using namespace std;
volatile bool stop = false;
DWORD WINAPI thread1(LPVOID pm)
{
for(int i=5;i>0 && !stop;i--)
{
cout<<"\n\n\n\n\n\n";
cout<<setw(35);
cout<<i;
Sleep(1000);
system("CLS");
}
return 0;
}
int main()
{
HANDLE handle = CreateThread(NULL, 0, thread1, NULL, 0, NULL);
//check the getchar value
int a = getchar();
while (a != '0'){
a = getchar();
}
stop = true;
WaitForSingleObject(handle, INFINITE);
system("PAUSE");
}
With this solution, it will stop after waiting 1s. If you want to terminate immediatly, you can use TerminateThread but read this before : https://msdn.microsoft.com/en-us/library/windows/desktop/ms686717%28v=vs.85%29.aspx
Found it. getchar() was waiting for carriage return. So i used _getch() from conio library. Like this.
#include<iostream>
#include<Windows.h>
#include<conio.h>
#include<stdlib.h>
#include<iomanip>
using namespace std;
volatile bool stop = false;
DWORD WINAPI thread1(LPVOID pm)
{
int a = 0;
while (a==0)
{
a = _getch();
}
stop = true;
return 0;
}
int main()
{
HANDLE handle = CreateThread(NULL, 0, thread1, NULL, 0, NULL);
int i;
for ( i = 5; i > 0 && !stop; i--)
{
cout << "\n\n\n\n\n\n";
cout << setw(35);
cout << i;
Sleep(1000);
system("CLS");
}
if (i != 0)
cout << "Loop broken sucessflly.\n";
else
cout << "Attempt failed\n";
system("PAUSE");
}

WinAPI's sleep doesn't work inside child thread

I'm a beginner and I'm trying to reproduce a rae condition in order to familirize myself with the issue. In order to do that, I created the following program:
#include <Windows.h>
#include <iostream>
using namespace std;
#define numThreads 1000
DWORD __stdcall addOne(LPVOID pValue)
{
int* ipValue = (int*)pValue;
*ipValue += 1;
Sleep(5000ull);
*ipValue += 1;
return 0;
}
int main()
{
int value = 0;
HANDLE threads[numThreads];
for (int i = 0; i < numThreads; ++i)
{
threads[i] = CreateThread(NULL, 0, addOne, &value, 0, NULL);
}
WaitForMultipleObjects(numThreads, threads, true, INFINITE);
cout << "resulting value: " << value << endl;
return 0;
}
I added sleep inside a thread's function in order to reproduce the race condition as, how I understood, if I just add one as a workload, the race condition doesn't manifest itself: a thread is created, then it runs the workload and it happens to finish before the other thread which is created on the other iteration starts its workload. My problem is that Sleep() inside the workload seems to be ignored. I set the parameter to be 5sec and I expect the program to run at least 5 secs, but insted it finishes immediately. When I place Sleep(5000) inside main function, the program runs as expected (> 5 secs). Why is Sleep inside thread unction ignored?
But anyway, even if the Sleep() is ignored, the program outputs this everytime it is launched:
resulting value: 1000
while the correct answer should be 2000. Can you guess why is that happening?
WaitForMultipleObjects only allows waiting for up to MAXIMUM_WAIT_OBJECTS (which is currently 64) threads at a time. If you take that into account:
#include <Windows.h>
#include <iostream>
using namespace std;
#define numThreads MAXIMUM_WAIT_OBJECTS
DWORD __stdcall addOne(LPVOID pValue) {
int* ipValue=(int*)pValue;
*ipValue+=1;
Sleep(5000);
*ipValue+=1;
return 0;
}
int main() {
int value=0;
HANDLE threads[numThreads];
for (int i=0; i < numThreads; ++i) {
threads[i]=CreateThread(NULL, 0, addOne, &value, 0, NULL);
}
WaitForMultipleObjects(numThreads, threads, true, INFINITE);
cout<<"resulting value: "<<value<<endl;
return 0;
}
...things work much more as you'd expect. Whether you'll actually see results from the race condition is, of course, a rather different story--but on multiple runs, I do see slight variations in the resulting value (e.g., a low of around 125).
Jerry Coffin has the right answer, but just to save you typing:
#include <Windows.h>
#include <iostream>
#include <assert.h>
using namespace std;
#define numThreads 1000
DWORD __stdcall addOne(LPVOID pValue)
{
int* ipValue = (int*)pValue;
*ipValue += 1;
Sleep(5000);
*ipValue += 1;
return 0;
}
int main()
{
int value = 0;
HANDLE threads[numThreads];
for (int i = 0; i < numThreads; ++i)
{
threads[i] = CreateThread(NULL, 0, addOne, &value, 0, NULL);
}
DWORD Status = WaitForMultipleObjects(numThreads, threads, true, INFINITE);
assert(Status != WAIT_FAILED);
cout << "resulting value: " << value << endl;
return 0;
}
When things go wrong, make sure you've asserted the return value of any Windows API function that can fail. If you really badly need to wait on lots of threads, it is possible to overcome the 64-thread limit by chaining. I.e., for every additional 64 threads you need to wait on, you sacrifice a thread whose sole purpose is to wait on 64 other threads, and so on. We (Windows Developer's Journal) published an article demonstrating the technique years ago, but I can't recall the author name off the top of my head.

C++ how do I terminate my programm using ESC button

Here is my main function i use visual studio 2012 express and the code works fine. My question is how will i terminate this loop when the user Presses the ESC button instead of -1. Although i would prefer a solution that works both in unix and windows, if it is not possible i am most interested in it working for windows.
int _tmain(int argc, _TCHAR* argv[])
{
list mylist;
int value;
cout<<"Give the numbers you want to insert to the list, press -1 to stop\n";
do
{
cin>>value;
mylist.insertf(value);
mylist.sort_list();
mylist.print();
}while(value!=-1);
}
Here are solution for Windows
First solution:
Esc will not be handled when user starts to type till pressing enter.
While idle Esc will be handled
#include <Windows.h>
#include <iostream>
#include <conio.h>
#include <vector>
int main(int argc, char **argv)
{
int value=0;
std::vector<int> mylist;
do
{
//check if any input.
if (_kbhit()){
//probable user started to type
//block to read till the user press Enter. If you want to handle Esc here .
//then you should manually do input reading . I will write that solution later
std::cin>>value;
//if success
if(std::cin.good()){
mylist.push_back(value);
}else{
//firstly, clear error flag
std::cin.clear();
//ignore
std::cin.ignore(10000,'\n');
}
//print list
std::cout<<"new list: { " ;
for(int i=0;i< mylist.size();i++){
std::cout<<mylist[i]<<'\t';
}
std::cout<<" }"<<std::endl;
}
//check if Esc Pressed
}while(GetAsyncKeyState(VK_ESCAPE)==0);
return 0;
}
Second Solution:
Esc will be handled always in another thread. Immediate exit can be undesirable on some cases
DWORD WINAPI CheckEscape( LPVOID lpParam ) {
while(GetAsyncKeyState(VK_ESCAPE)==0){
//sleep
Sleep(10);
}
exit(0);
}
int main(int argc, char **argv)
{
int value=0;
std::vector<int> mylist;
//create thread for handling ESC key
CreateThread( NULL, 0, CheckEscape,NULL , 0, NULL);
//loop infinitely
while(true)
{
std::cin>>value;
//if success
if(std::cin.good()){
mylist.push_back(value);
}else{
//firstly, clear error flag
std::cin.clear();
//ignore
std::cin.ignore(10000,'\n');
}
//print list
std::cout<<"new list: { " ;
for(int i=0;i< mylist.size();i++){
std::cout<<mylist[i]<<'\t';
}
std::cout<<" }"<<std::endl;
}
return 0;
}
Third Solution and the Best one .Do everything manually
Handling keypress manually.
Exit will be called when Esc is Pressed. You can change it to handle more right way
bool keypress( char &key){
INPUT_RECORD IR[1];
DWORD read;
static HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
while(PeekConsoleInputA(h,IR,1,&read)){
if(read!=0){
//check if it was Key Event
if(IR[0].EventType==KEY_EVENT){
key=IR[0].Event.KeyEvent.uChar.AsciiChar;
ReadConsoleInputA(h,IR,1,&read);
FlushConsoleInputBuffer(h);
return true;
}
if(ReadConsoleInputA(h,IR,1,&read)){
continue;
}
}else{
return false;
}
}
}
//getnumber
int cinnumb( ){
char buffer[32];
buffer[0]='\0';
int count=0;
DWORD key=-1;
while(true){
Sleep(100);
do{
//here I make it nonblockin keypress
//but actually we do not need it
//we can use blocking ReadConsoleInputA(h,IR,1,&read);
//this way we not even need sleep() and
//our keypress function will be simple
//anyway im posting nonblocking one
//nonblocking keypress
char key=0;
bool isOk=keypress(key );
if(!isOk ){
Sleep(20);
continue;
}
if(key>='0' && key<='9'){
buffer[count]=key;
std::cout<<key;
++count;
if( count==31)break;
}
// check Enter key and enough symbol
if( key==13 && count>0 ){
std::cout<<std::endl;
break;
}
//for windows
//check if Esc pressed
if(key==27) exit(0);
}while(true);
buffer[count]='\0';
int value=atoi(buffer);
return value;
}
}
int main(int argc, _TCHAR* argv[])
{
std::vector<int> mylist;
int value;
char buffer[100];
//infinite loop
while(true)
{
//get number
value=cinnumb();
mylist.push_back(value);
//print list
std::cout<<"new list: { " ;
for(int i=0;i< mylist.size();i++){
std::cout<<mylist[i]<<'\t';
}
std::cout<<" }"<<std::endl;
//sleep a little
Sleep(10);
} ;
return 0;
}