Using KeyPress in C++ from string input creates errors - c++

Solved: Check the void SendInputString( std::wstring &str) function in this answer
I am developing an executable in C++ which can be given a string as a command-line parameter and it will be typed emulating the keyboard; using keypresses.
In the format on command line:
{program name} {string to reproduce} {time between individual keypresses in ms}
This is my code:
#define WINVER 0x0500
#include <windows.h>
void chartype(char x , INPUT &input, unsigned int pause_time){
input.ki.wVk=VkKeyScanA(x);
//Verifies character and allots the key to the keyboard
//cout<<x; //Old check code
Sleep(pause_time);
SendInput(1,&input,sizeof(INPUT));
//To send input
return;
}
int main(int argc , char** argv){
//Initializing a GUI Keyboard Set
INPUT input;
input.type=INPUT_KEYBOARD;
//Assigning Input Variables
string str = argv[1];
size_t n = str.size();
unsigned int pause_time = stoi(argv[2]);
//Sending individual string characters
for(size_t i =0 ; i<n ; ++i){
chartype(str[i] , input , pause_time);
}
//Shutting Keyboard
input.ki.dwFlags=KEYEVENTF_KEYUP;
SendInput(1, &input,sizeof(INPUT));
return 0;
}
However, the string is not exactly executed. For example if I input the string PASS_INPUT, it renders pass-input. Also, the output is sensitive to whether or not Caps Lock is on or not.
I assume it is happening because it only kind of emulates pressing the specific key on the keyboard, and thus assumes a default value, however I want it to present exact outputs, such as %9Xa{ to give %9Xa{ and not 59xa[ which is happening presently.
I am sorry if I could not frame the question well enough. I am new to this keyboard emulation, and am not able to exactly understand what to do.
I would like to know what modification should be made to render the string as expected.

Can use the function SendInputString( std::wstring &str) from this answer

Related

How to automatically put newline at text's end in FLTK Multiline_Input?

I am using FLTK 1.3.5 and I would like to use the Multiline_Input object. I wonder if there is a way to automatically put a newline when the inserted text reaches the end of the input field, instead of doing it manually (check the uploaded images for an example). Moreover, the newline should be put at the end of a word. I searched here on SO and on the web, but I was not able to find anything useful.
Here it is the code used to generate the images above.
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Multiline_Input.H>
int main(int argc, char **argv) {
Fl_Window *G_win = 0;
G_win = new Fl_Window(200,200,"Test multi input");
Fl_Multiline_Input* in;
in = new Fl_Multiline_Input(50,50,120,100," Test:");
G_win->end();
G_win->show(argc, argv);
return Fl::run();
}
With FLTK, you can always catch keyboard events, e.g. using (or redefining) keyboard events
A human being don't type very fast, and computers are fast. Your keyboard event handler could change the multiline content at every keystroke
We plan to do so (in summer 2020) in the RefPerSys project.
Following Basile's suggestion, I investigated more on handling events and then I came up with a solution.
I derivated a class from the original Fl_Multiline_Input which basically controls that the char[] in Fl_Multiline_input->value() does not overcome the maximum width given by the geometry (considering the current Fl_font). Maybe it is not the best solution but, hey, it works! Of course, more performant/elegant strategies are more than welcome.
The code is down below.
#include "mymulti.hpp"
/*
This is needed for converting a std::string
to a char[] (required by Fl_Input). Again,
maybe more performant alternative are out there...
*/
char* str2char(std::string S){
char *out;
out = (char*) malloc ((S.size()+1)*sizeof(char));
strcpy(out,&S[0]);
out[S.size()] = '\0';
return out;
}
mymulti::mymulti(int x, int y, int h, int l):Fl_Multiline_Input(x, y, h,l)
{}
int mymulti::handle(int event)
{
switch (event) {
// When a key is pressed and the widget is waiting for input
case FL_KEYBOARD:
return handle_key(event, Fl::event_key());
default:
return Fl_Multiline_Input::handle(event);
};
}
int mymulti::handle_key(int event, int key) {
if (key==FL_BackSpace)
// Allowing Fl_Multiline_Input to handle the delection of characters
return Fl_Multiline_Input::handle(event);
else{
// Converting to std::string just because manipulation is easer
std::string s(this->value());
std::string s2;
/*
Search for the last newline char:
the subsequent substring must be shorter
than the width of the input field
*/
std::size_t found = s.find_last_of("\n");
if (found<std::string::npos)
s2= s.substr (found);
else
s2 = s;
/*
Mean length of a char (lower case)
under the current fl_font. One can add
uppercase letters and/or numbers and/or
other symbols.
*/
double lc = fl_width("abcdefghijklmnopqrstuvwxyz")/26;
// Maximum length for the substring
int string_length = this->w()/lc -1;
// if the substring is longer than the max allowed length, then add a newline
if (s2.length()>string_length)
s+="\n";
// Update the input field
this->value(str2char(s));
return Fl_Multiline_Input::handle(event);
}
}

Replacements for deprecated strcpy/strcat when using char*

I have code for a 'zombie translator' as an example from my professor. From what I can tell it takes a string of english words and applies a few rules to it via functions. It currently uses strcpy and strcat to do this, however it will not compile even if I change them to strcpy_s. Without including the other functions (for the sake of space), here is my main function as an example
int main()
{
char english[MAX];
char zombie[MAX];
char zombie_word[MAX];
int pos_e; /* Current position in english line of text */
int pos_z; /* Current position in line of translated zombie text */
while (1) {
pos_e = 0;
pos_z = 0;
strcpy(zombie, "");
cout << ("Enter English text: ");
cin >> english;
/* This loop translates the line from english to zombie. */
do
{
get_next_word(english, &pos_e, zombie, &pos_z);
translate_word(english, &pos_e, zombie_word, &pos_z);
strcat(zombie, zombie_word);
} while (pos_e < strlen(english));
print_translation(zombie);
}
return 0;
}
So more specifically, what should i do to the line strcat(zombie, zombie_word); to make it compile properly in Visual Studio 2015?
It's not for a grade, I just really want to be able to understand this before the midterm, and it's a bit difficult to play around with it. I would prefer not to have to disable it through _CRT_SECURE_NO_WARNINGS so that I know what to do if I need to do something similar.
Perhaps changing the char variables into strings or something like that? I've been looking around for awhile and can't find the actual process.
Thank you very much for any assistance, I greatly appreciate your time.
From Microsoft: strncat_s
You need to include the length of the array to prevent buffer overflow dangers.
The API is:
errno_t strncat_s(
char *strDest,
size_t numberOfElements,
const char *strSource,
size_t count
);
numberOfElements is size of destination array.

CMD Prompt C++: Limiting literals entered on screen

I hope the question isn't to ambiguous.
when I ask:
int main()
{
string name = {""};
cout << "Please enter a name: " << endl;
getline(cin, name);
//user enters 12 characters stop displaying next literal keypresses.
enter code here
}
I would like to be able to limit the amount of times the user can enter a char on screen. Example, the screen stops displaying characters after length 12?
If so what would be the library and command line for doing something like this?
Wanting to this as, I have a ascii art drawn on the CMD, and when I cout the statement at x,y anything over 12 characters long inputed draws over the ascii art.
I hope this makes sense :'{ Thank you!
By default the console is in cooked mode (canonical mode, line mode, ...). This means
that the console driver is buffering data before it hands it to your application
characters will be automatically echoed back to the console by the console driver
Normally, this means that your program only ever gets hold of the input after a line ends, i.e. when enter is pressed. Because of the auto-echo, those character are then already on screen.
Both settings can be changed independently, however the mechanism is --unfortunately-- an OS-specific call:
For Window it's SetConsoleMode():
HANDLE h_stdin = GetStdHandle(STD_INPUT_HANDLE);
DWORD mode = 0;
// get chars immediately
GetConsoleMode(hStdin, &mode);
SetConsoleMode(hStdin, mode & ~ENABLE_LINE_INPUT));
// display input echo, set after 12th char.
GetConsoleMode(hStdin, &mode);
SetConsoleMode(hStdin, mode & ~ENABLE_ECHO_INPUT));
As noted by yourself, Windows still provides conio.h including a non-echoing _getch() (with underscore, nowadays). You can always use that and manually echo the characters. _getch() simply wraps the console line mode on/off, echo on/off switch into a function.
Edit: There is meant to be an example on the use of _getch(), here. I'm a little to busy to get it done properly, I refrained from posting potentially buggy code.
Under *nix you will most likely want to use curses/termcap/terminfo. If you want a leaner approach, the low level routines are documented in termios/tty_ioctl:
#include <sys/types.h>
#include <termios.h>
struct termios tcattr;
// enable non-canonical mode, get raw chars as they are generated
tcgetattr(STDIN_FILENO, &tcattr);
tcattr.c_lflag &= ~ICANON;
tcsetattr(STDIN_FILENO, TCSAFLUSH, &tcattr);
// disable echo
tcgetattr(STDIN_FILENO, &tcattr);
tcattr.c_lflag &= ~ECHO;
tcsetattr(STDIN_FILENO, TCSAFLUSH, &tcattr);
You can use scanf("%c",&character) on a loop from 1 to 12 and append them to a pre-allocated buffer.
As in my comments, I mentioned a method I figured out using _getch(); and
displaying each char manually.
simplified version:
#include <iostream>
#include <string>
#include <conio.h>
using namespace std;
string name = "";
int main()
{
char temp;
cout << "Enter a string: ";
for (int i = 0; i < 12; i++) { //Replace 12 with character limit you want
temp = _getch();
name += temp;
cout << temp;
}
system("PAUSE");
}
This lets you cout each key-press as its pressed,
while concatenating each character pressed to a string called name.
Then later on in what ever program you use this in, you can display the full name as a single string type.

Decode a message without a key

Here is what I should do
making a program that reads a text file that contains encrypted message and crack it it is kind of close to substitution cipher where I should swap swap each letter back with another meaning like shifting B back to A if its being shifted by one, and try comparing shifted words by some common used words to find if 2 of the common words have been found on the shifted ones
ex: shift the word by one
check when you shifted it is there 2 common words found?
no keep going
yes means thats it stop shifting
Now this issue here which makes the program hard for me is that I do not have a key to be entered it would've been awesome if I had it.
3 issues I am having now, is in my void function it will not print anything,
the second issue is, even if I fix my issue (I know this because in my function I have added something to convert string to c_string) and the issue is it will not shift until it finds the words I am looking which I have declared in string "Common[]"
3rd issue is whenever I compile I get an error invalid conversion from const char** to char comparison between signed and unsigned integer expressions
#include <iostream>
#include <fstream>
#include <string>
#include <stdio.h>
#include <ctype.h>
using namespace std;
void makeshift (string encrypt, int key)
{
for (int i = 0 ; i<encrypt.size();i++)
{
cout<<encrypt<<endl; // to see what is in file way to debug
const char *encryptedc; // this is to convert string to cstring
encryptedc = encrypt.c_str();
encryptedc-=key;
cout<<"decrypted message is "<<encryptedc<<endl;
}
}
int main (int argc, char* argv[])
{
// this will make me compare between encrypted message to check if it
// contains this words or not!
const char* common[]{"the","and","in","he","with","that","as","at","do"};
string encrypted; // The encrypted message gotten from file
ifstream message(argv[1]); // get file name typed by user
if(message.is_open()) // check if file is open
{
while (!message.eof()) // check if we reached end of file
{
// get the whole line in file
getline(message,encrypted);
///loop throgh it to store numbers in declared varibles
for (int i = 0 ; i < encrypted.size();i++)
{
makeshift(encrypted,i);
// here is where the error occurs which is "invalid conversion
// from const char to char
if(encrypted.find(common) != -1)
{
cout<<"found common"<<endl;
cout<<encrypted<<endl;
break;
}
}
}
}
}
Compile error
First, you say you're getting a compile error on this line:
if(encrypted.find(common) != -1)
The reason for that is because find() expects its argument to be a string, but common is an array of strings. In other words, find() can only search for one word at a time. It can't search for a whole list of words.
To fix that, you'll want to write a loop and check one word each iteration.
Shift function
Next up is the makeshift function. A couple of suggestions there.
There's no real need to call c_str(). You can change encrypted directly by modifying each encrypted[i] in the loop.
It needs to return the result. If you modify encrypted but do not return it then the caller won't see the result.
The printouts ought to be outside the loop. Presumably you just want to see the before and after results after you've decrypted the entire string.
Here's what it looks like with those issues addressed:
string makeshift (string encrypt, int key)
{
cout << encrypt << endl; // to see what is in file way to debug
for (int i = 0 ; i<encrypt.size();i++)
{
encrypted[i] -= key;
}
cout << "decrypted message is " << encryptedc << endl;
return encrypted;
}
And then you would call it as:
string decrypted = makeshift(encrypted, i);
By the way, I'm not sure if the encrypted[i] -= key; line is completely correct. My guess is you'll need to handle wraparound. Like if you subtract 3 from the letter "A" you should probably wrap around to "X", correct? If so, I'll leave that as a TODO for you.
I/O error checking
Lastly, let's talk about I/O. Specifically, this bit of code:
ifstream message(argv[1]); // get file name typed by user
if(message.is_open()) // check if file is open
{
while (!message.eof()) // check if we reached end of file
{
// get the whole line in file
getline(message,encrypted);
...
}
}
A good practice in C++ is to check the results of I/O operations (e.g. getline). After you read a line you need to check that the read actually worked. You don't want to continue on if getline() failed (say, because it hit end-of-file).
Conveniently, if you write while (getline(...)) then that'll do a whole bunch of things all at once--it'll check if the file is open, if it's at EOF, and it'll read lines and tell you if the reads were successful. That means you can replace the stuff above with a single loop:
ifstream message(argv[1]); // get file name typed by user
while (getline(message, encrypted))
{
...
}
You are passing the value of encrypted to makeshift, so whatever you do in makeshift function will not change the encrypted in main function
you have 2 solutions here:
you can either pass the pointer of encrypted to the makeshift function
void makeshift (string* encrypt, int key){
for (int i = 0 ; i<encrypt.size();i++)
{ cout<<encrypt->c_str()<<endl; // to see what is in file way to debug
const char *encryptedc; // this is to convert string to cstring
encryptedc = encrypt->c_str();
encryptedc-=key;
cout<<"decrypted message is "<<encryptedc<<endl;
}
}
int main (int argc, char* argv[]){
...
makeshift(&encrypted, i);
...
}
Or you can return the value of encryptedc and assign it back to encrypted in main function
string makeshift (string encrypt, int key){
for (int i = 0 ; i<encrypt.size();i++)
{ cout<<encrypt.c_str()<<endl; // to see what is in file way to debug
const char *encryptedc; // this is to convert string to cstring
encryptedc = encrypt.c_str();
encryptedc-=key;
cout<<"decrypted message is "<<encryptedc<<endl;
return encryptedc; //you can assign const char* to string
}
}
int main (int argc, char* argv[]){
...
encrypted = makeshift(encrypted, i);
...
}

Program for Password in C++

Password program not working....pls help....for right input also it says wrong password
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<iostream.h>
void main()
{
clrscr();
int ctr=0;
int o;
char pass[5];
cout<<"enter password";
for(int i=0;i<5 && (o=getch())!=13 ;i++)
{
pass[i]=o;
putch('*');
}
ctr=strcmp(pass,"luck");
cout<<ctr;
if(ctr==0)
{
cout<<"welcome";
}
else
{
cout<<"wrong password";
}
getch();
}
I want to know why this password program not working....is their any other way
To be able to use strcmp(), you need to NUL-terminate pass. You also need to make sure that pass is large enough to accommodate the NUL.
As <conio.h> is in use, I'm assuming Windows is being used. For those who are interested, here is a start on the proper way to do this. I input a line as the password, ending when enter is pressed, and don't show asterisks, as they give away the length pretty easily.
//stop echoing input completely
HANDLE inHandle = GetStdHandle(STD_INPUT_HANDLE); //get handle to input buffer
DWORD mode; //holds the console mode
GetConsoleMode(inHandle, &mode); //get the current console mode
SetConsoleMode(inHandle, mode & ~ENABLE_ECHO_INPUT); //disable echoing input
//read the password
std::string password; //holds our password
std::getline(std::cin, password); //reads a line from standard input to password
//compare it with the correct password
std::cout << (password == "luck" ? "Correct!\n" : "Wrong!\n"); //output result
//return console to original state
SetConsoleMode(inHandle, mode); //set the mode back to what it was when we got it
Of course there are things you can do to improve it (a hardcoded password string is never a good thing), and go ahead and do so if you wish, but the point is that it works as a basic password input system and has an easy-to-follow structure. You can still use the things you love when getting a password input, rather than going one character at a time and resorting to C strings and code.