How to pause my console on the desired key - c++

I want to pause my program on the 0x32, 0x33 and 0x34 key and make it work again on the 0x31 key, how can I? I used this code to pause on the 0x32 key, it's working, but I can't get it back to work on the desired key

To summarize what #user4581301 suggested:
#include <conio.h>
...
if (GetAsyncKeyState(0x32) || GetAsyncKeyState(0x33) || GetAsyncKeyState(0x34)) {
while (_getch() != 0x31)
;
}

If your application is a console application, I implemented the function you want through loop. If it's a desktop application, you can refer to my code logic.
#include <iostream>
#include<cstdlib>
#include<time.h>
#include<Windows.h>
#include<conio.h>
using namespace std;
int main()
{
while (true) {
for (int i = 0; i < 5; ++i) {
if (GetAsyncKeyState(gun_keys[i]) && (gun != guns[i])) {
gun = guns[i];
system("cls");
gun_delay = GetTime(gun->rpm);
gun_index = 0;
break;
}
}
if (GetAsyncKeyState(VK_DELETE)) //Bind key, what close this program
{
ExitProcess(-1); //Exit Process
}
if (GetAsyncKeyState(MOUSEEVENTF_MOVE) < 0) {
if (!is_mouse_down) {
is_mouse_down = true;
if (gun != nullptr)
gun_index = 0;
}
if (gun != nullptr && gun_index != gun->len) {
mouse_event(MOUSEEVENTF_MOVE, long(gun->pattner[gun_index][0] * K), long(gun->pattner[gun_index][1] * K), 0, 0);
++gun_index;
Sleep(gun_delay);
continue;
}
}
else
is_mouse_down = false;
if (_kbhit())//Checks if there is currently keyboard input and returns a non-zero value if there is, or 0 otherwise
{
int ch = _getch();
if (ch == 0x32 || ch == 0x33 || ch == 0x34)
{
ch = _getch();//It waits for input and pauses the program
}
if (ch != 0x31)
{
while (true)
{
if (_kbhit())
{
int ch = _getch();
if (ch == 0x31) break;
}
}
}
fflush(stdin);//Clear the input buffer
}
Sleep(150);
}
return 0;
}

Related

How to make std::cout discarding certain symbols at its output

There is a device sending byte stream using UTF-8. Among them ESC symbols present, such as 0x1B[?25h 0x1B[nJ 0x1B[u etc. which are later printed with std::cout.
How to force std::cout to discard this ANSI escape code sequencies in printing outside?
Since I am working with Qt's QSerialPort I will convey the code I made according this enviroment
void removeCtrlSeq(QByteArray &data)
{
char csi = 0x1B;
if (data.contains(csi))
{
bool inSearchForSci = true; // flag of search activity (CSI symbol)
unsigned int p = 0;
for (unsigned int s = 0; s < data.length(); ++s)
{
if (inSearchForSci == true && static_cast<unsigned char>(data[s]) == csi)
{
inSearchForSci = false; // here we found the begining of sequence - so we freez search for future steps
}
else
{
if (inSearchForSci == false && ((static_cast<unsigned char>(data[s]) >= 0x41 && static_cast<unsigned char>(data[s]) <= 0x5A) ||
(static_cast<unsigned char>(data[s]) >= 0x61 && static_cast<unsigned char>(data[s]) <= 0x7A)))
{
inSearchForSci = true; // here we found the end of sequence - so make search active again
s++;
continue;
}
}
if (inSearchForSci == true)
{
data[p++] = data[s];
}
}
data.resize(p);
}
}

How to pause and unpause my program on the desired key

My program makes simple movements with the mouse, I use c++, it works through the console, I would like to pause on the ''0x32, 0x33, 0x34'' key and make it work again on the ''0x31'' key
if (GetAsyncKeyState(MOUSEEVENTF_MOVE) < 0) {
if (!is_mouse_down) {
is_mouse_down = true;
if (gun != nullptr)
gun_index = 0;
}
if (gun != nullptr && gun_index != gun->len) {
mouse_event(MOUSEEVENTF_MOVE, long(gun->pattner[gun_index][0] * K), long(gun->pattner[gun_index][1] * K), 0, 0);
++gun_index;
Sleep(gun_delay);
continue;
}
}
else
is_mouse_down = false;
Sleep(150);
}
return 0;
}

Verification code doesn't work in Arduino

I am new to Arduino and I'm trying to make a program that receives IR codes from a TV remote, uses them as a 4 number pass code lighting up a LED as you press each button. And then comparing the code to a hard-coded one. In this case 1234.
I made a function to verify that the value entered is equal to the pass. If so, light up a green LED and else, light up a red one.
However, even if I input the correct code, only the red led lights up.
Here is my whole code as I'm not sure which part of it is the one causing problems:
const int pass[4] = {1, 2, 3, 4};
int value[4] = {};
int digitNum = 0;
int input;
void loop()
{
value[digitNum] = input; //where input is a number between 0 and 9
digitNum++;
if(digitNum == 1){
lightFirstLed();
}
else if(digitNum == 2){
lightSecondLed();
}
else if(digitNum == 3){
lightThirdLed();
}
else if(digitNum == 4){
lightFourthLed();
verify();
}
}
void verify()
{
bool falseCharacter = false;
for(int i = 0; i <= 4; i++){
if(value[i] != pass[i]){
falseCharacter = true;
}
}
if(!falseCharacter){
lightGreenLed();
}
else{
lightRedLed();
}
}
Functions in the form of light*Led actually do what they're supposed to do.
I tried changing the verify function around, that ended up making the green LED the one that always shone. I've been doing this for hours and I'm starting to feel disparate.
I would really appreciate any help. And please tell me if anything I'm doing does not comply with best practices even if it's out of the scope of this question.
For full code and design, here's a link to autodesk's simulator: https://www.tinkercad.com/things/0keqmlhVqNp-mighty-leelo/editel?tenant=circuits?sharecode=vVUD2_4774Lj4PYXh6doFcOqWUMY2URIfW8VXGxutRE=
EDIT: Now reset doesn't work
Your for loop in verify is accessing outside the array:
const int pass[4] = {1, 2, 3, 4};
int value[4] = {};
for(int i = 0; i <= 4; i++){
if(value[i] != pass[i]){
falseCharacter = true;
}
}
Change i <= 4 to i < 4. Also, when falseCharacter is set to true, break from the loop:
for(int i = 0; i < 4; i++)
{
if(value[i] != pass[i])
{
falseCharacter = true;
break;
}
}
Update
You need an else statement in loop:
void loop(void)
{
if(irrecv.decode(&results))
{
if (results.value == powBtn)
{
reset();
}
else if (results.value == zeroBtn)
{
input = 0;
}
else if (results.value == oneBtn)
{
input = 1;
}
else if (results.value == twoBtn)
{
input = 2;
}
else if (results.value == threeBtn)
{
input = 3;
}
else if (results.value == fourBtn)
{
input = 4;
}
else if (results.value == fiveBtn)
{
input = 5;
}
else if (results.value == sixBtn)
{
input = 6;
}
else if (results.value == sevenBtn)
{
input = 7;
}
else if (results.value == eightBtn)
{
input = 8;
}
else if (results.value == nineBtn)
{
input = 9;
}
else
{
return; /*** !!! Unrecognized Value !!! ***/
}
value[digitNum] = input;
digitNum++;
if(digitNum == 1)
{
digitalWrite(LED1, HIGH);
}
else if(digitNum == 2)
{
digitalWrite(LED2, HIGH);
}
else if(digitNum == 3)
{
digitalWrite(LED3, HIGH);
}
else if(digitNum == 4)
{
digitalWrite(LED4, HIGH);
verify();
}
else
{
if (results.value == powBtn)
{
reset();
}
}
// Receive the next value
irrecv.resume();
}
}

Fork: Resource temporarily unavailable when running shell with one arg

I am trying to write a microshell in C++ that will take in 1 or 2 args and run them in UNIX. My shell takes two args split by || fine, but when I run only one I get a massive fork error. My shell will look for || as a pipe instead of just |. Thank you in advance!
Some Functional commands are:
cat filename || sort
ls -l || less
Code:
#include <iomanip>
#include <iostream>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <stdio.h>
using namespace std;
void getParms (char[], char* [], char* []);
int main()
{
char command[160];
pid_t pid1 = 1, pid2 = 1;
cout << "myshell> ";
cin.getline(command, 160);
while (strcmp(command, "q") != 0 && strcmp(command, "quit") != 0 && pid1 > 0 && pid2 > 0)
{
char* arg1[6];
char* arg2[6];
char path1[21], path2[21];
int pipefd[2];
arg1[0]=NULL;
arg2[0]=NULL;
getParms(command, arg1, arg2);
if (pipe(pipefd) < 0)
{
perror ("Pipe");
exit (-1);
}
//cerr <<"This is arg2"<<arg2[0]<<endl;
pid1 = fork();
if (pid1 < 0)
{
perror ("Fork");
exit (-1);
}
if (pid1 == 0)
{
//cout<<"Child 1"<<endl;
//cerr<<arg1[0]<<endl;
if(arg2[0] != NULL)
{
close(pipefd[0]);
close(1);
dup(pipefd[1]);
close(pipefd[1]);
}
strcpy(path1, "/bin/");
strcat(path1, arg1[0]);
if (execvp(path1, arg1) < 0)
{
strcpy(path1, "/usr/bin/");
strncat(path1, arg1[0], strlen(arg1[0]));
if (execvp(path1, arg1) < 0)
{
cout<<"Couldn't execute "<<arg1[0]<<endl;
exit (127);
}
}
if(arg2[0]== NULL)
{ // Parent process
close (pipefd[0]); //read
close (pipefd[1]); //write
waitpid(pid1, NULL, 0); // Waits for child2
cout << "myshell> ";
cin.getline(command, 160);
}
}
else if(arg2[0] != NULL)
{
//cerr<<"Child 2"<<endl;
pid2 = fork();
if (pid2 < 0)
{
perror ("Fork");
exit (-1);
}
if (pid2 == 0)
{
close(pipefd[1]);
close(0);
dup(pipefd[0]);
close(pipefd[0]);
strcpy(path2, "/bin/");
strncat(path2, arg2[0], strlen(arg2[0]));
if (execvp(path2, arg2) < 0)
{
strcpy(path2, "/usr/bin/");
strncat(path2, arg2[0], strlen(arg2[0]));
if (execvp(path2, arg2) < 0)
{
cout<<"Couldn't execute "<<arg2[0]<<endl;
exit (127);
}
}
}
else
{ // Parent process
//cerr<<"in last 2 else"<<endl;
close (pipefd[0]); //read
close (pipefd[1]); //write
waitpid(pid2, NULL, 0); // Waits for child2
cout << "myshell> ";
cin.getline(command, 160);
}
}
}
return 0;
}
/****************************************************************
FUNCTION: void getParms (char [], char* [], char* [])
ARGUMENTS: char str[] which holds full command
char* args[] args2[] which will hold the individual commands
RETURNS: N/A
****************************************************************/
void getParms(char str[], char* args[], char* args2[])
{
char* index;
int i= 0;
int j= 0;
index = strtok(str, " ");
//cerr<<"before first while"<<endl;
// While the token isn't NULL or pipe
while (index != NULL && strstr(index,"||") == NULL)
{
args[i] = index;
index = strtok(NULL, " ");
i++;
}
args[i] = (char*) NULL; // makes last element Null
//cerr<<" getParms before ||"<<endl;
if(index != NULL && strcmp(index,"||") != 0)
{
//cerr<<"after checking for ||"<<endl;
index = strtok(NULL," ");
while (index != NULL)
{
args2[j] = index;
index = strtok(NULL," ");
j++;
}
}
//cerr<<"After second IF"<<endl;
args2[j] = (char*) NULL; // makes last element Null
}
Your problem is that the main while loop is not going to any of the if-else statements in which you have the prompt for another command - the same statement is executed over and over. When you use the double pipe it goes to else if(arg2[0] != NULL) and the parent process shows a new prompt.
Try removing both prompts for a command from the main while loop in your if-else statement and move the prompt to the beginning of the loop like this:
//Move these two below into the while loop
//cout << "myshell> ";
//cin.getline(command, 160);
while (strcmp(command, "q") != 0 && strcmp(command, "quit") != 0 && pid1 > 0 && pid2 > 0)
{
cout << "myshell> ";
cin.getline(command, 160);
//...
}
Try not to make such redundant calls of the same thing. If you have a couple of those and you need to change something it can get messy.

batch processing in a simple shell

Hey folks I am making a batch command function in a shell that reads from a txt file and pipes it to a child to exec.
I'm having an issue with exec. I suspect it is something with the null terminator. If I execl with an L and an explicit (char*)NULL the exec runs. If I execvp(argIn[0],argIn) nothing runs and returns a -1. If I execvp with an explicit (char*)NULL I get an error cannot convert char* to char* constant*. I read somewhere that it might be the g++ compiler giving me the error but the gcc compiler wouldn't give the error. Right now it won't compile with gcc though so I'm not sure if that's true. But it shouldn't need the explicit terminator anyway. I'm not sure if the '\0' I have stored is being passed to the exec right. It checks out when I pass it to other functions though so maybe that's not the solution.
Second, my for loop won't exec more than once which I think is more to do with the first solution. I can get the execl to fork with an index but I can't increment the index to point to the right token the next time through because the child should be wiping out my index right?
Anyway it's been 3 weeks of digging to figure out what's wrong. I failed the assignment. Probably going to fail the class. I don't know what else to try. So any help I would appreciate.
My question is why would the exec function not execute the program? I'm passing execvp(program name, program name, option, option, '\0') and not getting a result.
or
execl(program name, program name[index], option[index+1], option[index+1], (char*)NULL) and getting a result. They both seem to be following the parameters but only one is giving me a result.
#include<string.h>
#include<iostream>
#include<ctype.h>
#include<stdlib.h>
#include<stdio.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
using namespace std;
int makearg(char s[], char**args[]);
int main(int argc, char *argv[])
{
char **argIn;
int argCount;
int pos = 0;
char str[500];
pid_t pid = fork();
for(int i = 0; i < 4; i++)
{
if(pid == 0)
{
while(fgets(str, 500, stdin) != NULL)
{
cout << "String loaded: " << str;
argCount = makearg(str, &argIn);
execvp(argIn[0],argIn); //nothing exec
// execl(argIn[0],argIn[0],argIn[1],argIn[2],(char*)NULL); //exec but requires index.
else if(pid < 0)
{
perror("fork() error");
exit(-1);
}
else if(pid > 0)
{
cout << "Parent waiting" << endl;
wait(NULL);
}
}
return 0;
}
int makearg(char s[], char**args[])
{
int counter = 1;
int tokenLen = 1;
int i = 0;
int j = 0;
int k = 0;
char arg1[50];
char * arg2;
strcpy(arg1, s);
//Count white space.
while (arg1[j] != '\0')
{
if (arg1[j] == ' ' || arg1[j] == '\0' || arg1[j] == '\n')
{
counter++;
}
j++;
}
//Allocate the number of rows to be pointed to.
args[0] = (char**) malloc(counter + 1);
if(args[0] == NULL)
exit(1);
//Allocate the size of the c string arrays
j = 0;
while(arg1[j] != '\0')
{
if (arg1[j] == ' ' || arg1[j] == '\0' || arg1[j] == '\n')
{
(*args)[i] = (char*)(malloc(tokenLen));
if((*args)[i] == NULL)
exit(1);
tokenLen = 0;
i++;
}
j++;
tokenLen++;
}
(*args)[i] = (char*)(malloc(tokenLen));
if ((*args)[i] == NULL)
exit(1);
//reset values
i = 0;
j = 0;
//Set arg2 to point to args row head. Transfer values from arg1 to arg2.
arg2 = ((*args)[i]);
while(arg1[j] != '\0')
{
if (arg1[j] != ' ' && arg1[j] != '\0' && arg1[j] != '\n')
{
arg2[k] = arg1[j];
k++;
}
else
{
arg2[k] = '\0';
i++;
k = 0;
arg2 = ((*args)[i]);
}
j++;
}
arg2[k] = '\0';
if (counter < 1)
{
return -1;
}
return counter;
}
I took your posted code, updated it to fix build errors and ran. I executed the simple command "ls" but I got the message
String loaded: ls
ls: cannot access '': No such file or directory
That indicated to me that makearg is not working correctly. Then, I added a function to help with diagnosing the problem.
void printArguments(char **args)
{
for ( int j = 0; args[j] != NULL; ++j )
{
printf("args[%d]: %s\n", j, args[j]);
}
}
and added a call to it from main, right after the call to makearg.
argCount = makearg(str, &argIn);
printArguments(argIn);
I got the output:
String loaded: ls
args[0]: ls
args[1]:
ls: cannot access '': No such file or directory
That indicated to me that makearg was not dealing with the end of the line correctly. It creates an empty argument.
I added couple of functions to trim whitespaces from the left and from the right. After that, the child process was able to execute "ls" correctly.
Here's the updated program.
#include<string.h>
#include<iostream>
#include<ctype.h>
#include<stdlib.h>
#include<stdio.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
using namespace std;
int makearg(char s[], char**args[]);
void printArguments(char **args)
{
for ( int j = 0; args[j] != NULL; ++j )
{
printf("args[%d]: %s\n", j, args[j]);
}
}
int main(int argc, char *argv[])
{
char **argIn;
int argCount;
char str[500];
pid_t pid = fork();
for(int i = 0; i < 4; i++)
{
if(pid == 0)
{
while(fgets(str, 500, stdin) != NULL)
{
cout << "String loaded: " << str;
argCount = makearg(str, &argIn);
printArguments(argIn);
execvp(argIn[0],argIn); //nothing exec
}
}
else if(pid < 0)
{
perror("fork() error");
exit(-1);
}
else if(pid > 0)
{
cout << "Parent waiting" << endl;
wait(NULL);
}
}
return 0;
}
void trimWhiteSpacesLeft(char s[])
{
int i = 0;
for ( ; isspace(s[i]); ++i );
if ( i == 0 )
{
return;
}
int j = 0;
for (; s[i] != '\0'; ++j, ++i )
{
s[j] = s[i];
}
s[j] = '\0';
}
void trimWhiteSpacesRight(char s[])
{
int len = strlen(s);
int i = len-1;
for ( ; i >= 0; --i )
{
if ( !isspace(s[i]) )
{
break;
}
}
s[i+1] = '\0';
}
int makearg(char s[], char**args[])
{
int counter = 1;
int tokenLen = 1;
int i = 0;
int j = 0;
int k = 0;
char arg1[50];
char * arg2;
strcpy(arg1, s);
// Trim whitespaces from both ends.
trimWhiteSpacesLeft(arg1);
trimWhiteSpacesRight(arg1);
//Count white space.
while (arg1[j] != '\0')
{
if (arg1[j] == ' ' || arg1[j] == '\0' )
{
counter++;
}
j++;
}
//Allocate the number of rows to be pointed to.
args[0] = (char**) malloc(counter + 1);
if(args[0] == NULL)
exit(1);
//Allocate the size of the c string arrays
j = 0;
while(arg1[j] != '\0')
{
if (arg1[j] == ' ' || arg1[j] == '\0' || arg1[j] == '\n')
{
(*args)[i] = (char*)(malloc(tokenLen));
if((*args)[i] == NULL)
exit(1);
tokenLen = 0;
i++;
}
j++;
tokenLen++;
}
(*args)[i] = (char*)(malloc(tokenLen));
if ((*args)[i] == NULL)
exit(1);
//reset values
i = 0;
j = 0;
//Set arg2 to point to args row head. Transfer values from arg1 to arg2.
arg2 = ((*args)[i]);
while(arg1[j] != '\0')
{
if (arg1[j] != ' ' && arg1[j] != '\0' && arg1[j] != '\n')
{
arg2[k] = arg1[j];
k++;
}
else
{
arg2[k] = '\0';
i++;
k = 0;
arg2 = ((*args)[i]);
}
j++;
}
arg2[k] = '\0';
if (counter < 1)
{
return -1;
}
return counter;
}