C++: Reading characters before pressing ENTER - c++

for like few hours now, I am trying to figure out how to read characters from cin before pressing ENTER (by using threads). I know about conio.h library but I prefer not to use it.
I wrote simple program that gets data from user and saves it in 'msg' string. Program has child thread that clears the console every second. What I want to do is:
User puts some data but doesn't press ENTER so it's not saved in 'msg' variable.
Console clears
send to cout the characters user typed, so he won't even notice that console was cleared.
PS. Sorry for my english, here's the program:
#include<iostream>
#include<string>
#include<winsock2.h>
#include<process.h>
#include<windows.h>
using namespace std;
void __cdecl ThreadProc( void * Args )
{
while( true ){
system("cls");
cout << "Input: ";
/*
char c;
while((c=cin.peek()) != '\n')
cin.get(c);
cout << c;
*/
Sleep(1000);
}
_endthread();
}
int main(){
HANDLE hThread =( HANDLE ) _beginthread( ThreadProc, 0, NULL );
while (true){
string msg;
getline(cin,msg);
cout << "MSG:" << msg << endl;
cin.clear();
fflush(stdin);
}
return 0;
}
EDIT:
Key-logger? Nah, I am doing console network chat. Currently server and client can chat with each-other. When new message is received or sent, it is saved in "vector<\string> chat" and console is refreshed below code:
void show_chat(){
system("cls");
for(unsigned int i =0;i<chat.size();i++){
cout << "[" << date[i].tm_hour << ":" << date[i].tm_min << ":" << date[i].tm_sec << "] " << chat[i] << endl;
}
cout << "Input: ";
}
So there is a problem if new message is received while user is writing his own message. Part of the message written before message system("cls") is lost on the screen.

To do what you want, you will need to incorporate a message queue and update method.
Can you do it the way you have presented? Sure, but it's going to be a major pain and there's no way to do this with cin.
Simply have a message queue on both sides, a current status of each client(able_to_receive_messages, unable, etc), and an update method that is called by each client is run after the user is once again able to receive messages.

Related

C++ ifstream is not reading the entire line from text file

I'm implementing a simple program using text files. Users can register/login accounts that are saved to a txt file.
One of the options is to post a message to a "Post board" that will store the user's name followed by all their posts.
For example:
Leo: Hello
Tony: Bye
I'm able to successfully read the text file and output the message to the console but the username is not displaying, only the message.
For refrence I have a postMessage() function that uses getline() to concatante the username using
ofstream << getUsername() + ": " + string::message.
I have quite a bit of code so I cannot share all of it, however, here are the pieces in question.
public:
char postMessage(User& currentUser, bool loggedIn) { //Will post a message to the board. Passes a User object.
if (loggedIn == false) {
std::cout << "You must be logged in to post!" << std::endl;
userLoginRegisterPrompt();
return 0;
}
char messageState; //Code to verify if message was posted.
std::string message; //Actual message string
std::cout << "Enter your text: " << std::endl;
std::cin.ignore(); //Clears string buffer.
getline(std::cin,message);
std::ofstream post("C:/Users/19097/Desktop/Programs/Registration/Registration/UserPosts/-Posts.txt", std::ios::app); //File with user posts.
post << currentUser.getUserName() << ": " << message << std::endl;
logAction(currentUser.getUserID(), "Made a post");
}
Here is the loadPosts() method to read from the text file and display it to console.
static bool loadPosts() { //Will be for viewing the post history.
std::ifstream post("C:/Users/19097/Desktop/Programs/Registration/Registration/UserPosts/-Posts.txt");
std::string line;
if (!post) {
std::cout << "No board exists!" << std::endl;
return false;
}
while (post >> line) {
getline(post, line);
std::cout << line << std::endl;
}
}
This is what some of the posts read like in the actual txt file.
This is what shows on the console when using loadPosts()

C++/Cheat Engine, Writing to memory in Google Chrome - WriteProcessMemory & ReadProcessMemory

In efforts to learn more C++, I have chosen - you know - something fun to do and that is writing to random application's memory. The code I have written seems to work on all applications but I am having difficulties getting it to work with Google Chrome tabs.
What I am trying to do is simply change my score on Slope (on y8.com) for which I have the memory address with the help of cheat engine. The problem seems to be retrieving the Process ID of the tab. Using Chrome's Task Manager, I translated the tab's address to hex, opened the process in cheat engine and found the score address.
Here the problem comes. Whenever I use GetWindowThreadProcessId(window, &processID); cout << processID, it doesn't print the ID which can be seen in chrome's task manager for the game's tab. In fact, it prints the ID of chrome as a whole (which I know because in chrome's task manager, "chrome" has that ID). And the score cannot be written to or read from chrome's processID. If I ignore this problem, buffer seems to always print as 0.. no changes.
I am very new to this, and expect myself not to know what I am talking about. If you test the game yourself, you'll have to find the address that your chrome is using at the time. But here's the code (I have commented out the WriteProcessMemory and put Read just so I get it working before I write anything):
#include <iostream>
#include <string>
#include <Windows.h>
using namespace std;
int main() {
int buffer = 0;
LPVOID address = (LPVOID)0x15E7E1B0FB8/*(0x000000000192DFA0 + 0x0000291D8FE04000 + 0x18)*/;
cout << "Begin playing the game and wait for the 0 score to appear" << endl;
HWND window = FindWindow(NULL, "Slope Game - Play online at Y8.com");
if (window) {
cout << "Game found running! You ready to hax?" << endl;
DWORD processID = 11180;
GetWindowThreadProcessId(window, &processID);
HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, false, processID);
if (handle) {
/*string hackedScoreInput = "0";
cout << "Desired Score: " << flush; getline(cin, hackedScoreInput);
int hackedScore = stoi(hackedScoreInput);
int suc = WriteProcessMemory(handle, address, &hackedScore, sizeof(hackedScore), NULL);
if (suc > 0) {
cout << "HAXED!" << endl;
CloseHandle(handle);
}
else {
cerr << GetLastError() << endl;
cerr << hackedScore << " of size: " << sizeof(hackedScore) << endl;
return 3;
}*/
while (true) {
ReadProcessMemory(handle, address, &buffer, sizeof(buffer), NULL);
cout << buffer << " at adress: " << processID << endl;
Sleep(100);
system("CLS");
}
}
else {
cerr << "Could not open the process" << endl;
return 2;
}
}
else {
cerr << "Error! Could not find window!" << endl;
Sleep(3000);
return 1;
}
return 0;
}
What's wrong with the code?
Modern browsers use multiple processes and there is no rule that says that a browser tab HWND has to be owned by the process where the web page "runs".
Some browser implementations might have one main process that hosts the UI including all tabs but the actual web page content might be rendered to a shared bitmap/memory in a different process where it is safe to run scripts etc.
Chrome is open source so you could take a look and see if there is a way to find out which render process renders a certain tab by looking at the child processes command line arguments.

How to use QProcess write correctly?

I need a program to communicate with a subprocess that is relying on in- and
output. The problem is that I am apparently not able to use QProcess correctly.
The code further down should create a QProcess, start it and enter the main while loop. In there it prints all the output created by the subprocess to the console and subsequently asks the user for input which is then passed to the subprocess via write(...).
Originally I had two problems emerging from this scenario:
The printf's of the subprocess could not be read by the parent process.
scanf in the subprocess is not receiving the strings sent via write.
As for (1), I came to realize that this is a problem caused by the buffering of the subprocess' stdout. This problem can be solved easily with fflush(stdout) calls or manipulations regarding its flushing behavior.
The second problem is the one I can't wrap my head around. write gets called and even returns the correct number of sent bytes. The subprocess, however, is not continuing its excecution, because no new data is written to its output. The scanf seems not to be receiving the data sent. The output given by the program is:
Subprocess should have started.
124 bytes available!
Attempting to read:
Read: This is a simple demo application.
Read: It solely reads stdin and echoes its contents.
Read: Input exit to terminate.
Read: ---------
Awaiting user input: test
Written 5 bytes
No line to be read...
Awaiting user input:
I am seriously stuck right here. Google + heavy thinking having failed on me, I want to pass this on to you as my last beacon of hope. In case I am just failing to see the forest for all the trees, my apologies.
In case this information is necessary: I am working on 64bit MacOS X using Qt5 and the clang compiler. The subprocess-code is compiled with gcc on the same machine.
Thank you very much in advance,
NR
Main-Code:
int main() {
// Command to execute the subprocess
QString program = "./demo";
QProcess sub;
sub.start(program, QProcess::Unbuffered | QProcess::ReadWrite);
// Check, whether the subprocess is starting correctly.
if (!sub.waitForStarted()) {
std::cout << "Subprocess could not be started!" << std::endl;
sub.close();
return 99;
}
std::cout << "Subprocess should have started." << std::endl;
// Check, if the subprocess has written its starting message to the output.
if (!sub.waitForReadyRead()) {
std::cout << "No data available for reading. An error must have occurred." << std::endl;
sub.close();
return 99;
}
while (1) {
// Try to read the subprocess' output
if (!sub.canReadLine()) {
std::cout << "No line to be read..." << std::endl;
} else {
std::cout << sub.bytesAvailable() << " bytes available!" << std::endl;
std::cout << "Attempting to read..." << std::endl;
while (sub.canReadLine()) {
QByteArray output = sub.readLine();
std::cout << "Read: " << output.data();
}
}
std::cout << "Awaiting user input: ";
std::string input;
getline(std::cin, input);
if (input.compare("exit") == 0) break;
qint64 a = sub.write(input.c_str());
qint64 b = sub.write("\n");
sub.waitForBytesWritten();
std::cout << "Written " << a + b << " bytes" << std::endl;
}
std::cout << "Terminating..." << std::endl;
sub.close();
}
Subprocess-Code:
int main() {
printf("This is a simple demo application.\n");
printf("It reads stdin and echoes its contents.\n");
printf("Input \"exit\" to terminate.\n");
while (1) {
char str[256];
printf("Input: ");
fflush(stdout);
scanf("%s", str);
if (strcmp(str, "exit") == 0) return 0;
printf("> %s\n", str);
}
}
P.s: Since this is my first question on SO, please tell me if something is wrong concerning the asking style.
Solution
After many many more trials & errors, I managed to come up with a solution to the problem. Adding a call to waitForReadyRead() causes the main process to wait until new output is written by the subprocess. The working code is:
...
sub.waitForBytesWritten();
std::cout << "Written " << a + b << " bytes" << std::endl;
// Wait for new output
sub.waitForReadyRead();
...
I still don't have a clue why it works this way. I guess it somehow relates to the blocking of the main process by getline() vs blocking by waitForReadyRead(). To me it appears as if getline() blocks everything, including the subprocess, causing the scanf call never to be processed due to race conditions.
It would be great, if someone who understands could drop an explanation.
Thank you for your help :)
NR
This will not work. You are waiting for the sent bytes to be written but you are not waiting for the echo. Instead you are entering the getline() function waiting for new user input. Keep in mind that two processes are involved here where each process can be delayed to any degree.
Apart from this you should consider building your Qt application asynchronously (having an event loop) instead of trying the synchronous approach. This way your Qt application can do things in parallel... e.g. reading input or waiting for input from the remote process while still not being blocked and able to accept user input.

Interpretation of homework requirements, involving client/server communication

I've been working on an assignment that asks us to implement some code provided to us that allows the creation of a server and client that can communicate. I was to fork a process in main, and then test the various request options available, and then measure the difference in time it took to do this via the child process, or locally using a function. I'm unsure if I've interpretated the requirements correctly though. On top of this, all the timing functions return 0 seconds. Not sure if this is correct or not. I'll post a small portion of the code.
Homework statement (only a small portion):
Measure the invocation delay of a request (i.e. the time between the
invocation of a request until the response comes back.) Compare that
with the time to submit the same request string to a function that
takes a request and returns a reply (as compared to a separate process
that does the same). Submit a report that compares the two.
The function declared before main:
string myfunc(string request){
//string myreq = request;
RequestChannel my_func_channel("control", RequestChannel::CLIENT_SIDE);
string reply1 = my_func_channel.send_request(request);
return reply1;
}
And how I interpreted the directions in code:
int main(int argc, char * argv[]) {
//time variables
time_t start, end;
double time_req_1, time_req_func;
cout << "client.C Starting...\n" << flush;
cout << "Forking new process...\n " << flush;
pid_t childpid = fork();
if(childpid == -1)
cout << "Failed to fork.\n" << flush;
else if(childpid == 0){
cout << "***Loading Dataserver...\n" << flush;
//Load dataserver
RequestChannel my_channel("control", RequestChannel::CLIENT_SIDE);
cout << "***Dataserver Loaded.\n" << flush;
time(&start);
string reply1 = my_channel.send_request("hello");
cout << "***Reply to request 'hello' is '" << reply1 << "'\n" << flush;
time(&end);
time_req_1 = difftime(end,start);
cout <<"\n\nRequest 1 took : "<< time_req_1 << flush;
}
else{//parent
time(&start);
string s = myfunc("hello");
time(&end);
time_req_func = difftime(end,start);
cout <<"\nmyfunc Request took: "<< time_req_func << "\n" << flush;
}
usleep(1000000);
}
This is an abbreviated version of my code, but contains everything you should need to figure out whats going on. Have I done what the directions stated? Also, is it likely that my 0 seconds results are correct?
The time it takes to do it once may be (probably is) too small to measure, so time how long it takes to do it many times and then work out how long each one took.

RtMidi MIDI control signals to Ableton Live

I'm trying to write a C++ app using RtMidi to send control signals via my Tascam FireOne MIDI Controller to Ableton Live. So far, I have it successfully sending Note On + Off Signals, Volume Up + Down Signals, etc. via my MIDI Controller to my digital piano using 'a' and 's' keypresses.
// midiout.cpp
#include <iostream>
using namespace std;
#include <signal.h>
#include <windows.h>
#include <conio.h>
#include "RtMidi.h"
int main()
{
std::vector<unsigned char> message;
int i, keyPress;
int nPorts;
char input;
RtMidiOut *midiout = 0;
// midiOUT
try {
midiout = new RtMidiOut();
// Check available ports.
nPorts = midiout->getPortCount();
if ( nPorts == 0 ) {
cout << "No ports available!" << endl;
goto cleanup;
}
// List Available Ports
cout << "\nPort Count = " << nPorts << endl;
cout << "Available Output Ports\n-----------------------------\n";
for( i=0; i<nPorts; i++ )
{
try {
cout << " Output Port Number " << i << " : " << midiout->getPortName(i) << endl;
}
catch(RtError &error) {
error.printMessage();
goto cleanup;
}
}
cout << "\nSelect an output port number :" << endl;
cin >> keyPress;
while( keyPress < 0 || keyPress >= midiout->getPortCount() )
{
cout << "\nIncorrect selection. Please try again :" << endl;
cin >> keyPress;
}
// Open Selected Port
midiout->openPort( keyPress );
keyPress = NULL;
bool done = false;
cout << "Press a key to generate a message, press 'Esc' to exit" << endl;
while(!done)
{
keyPress = _getch();
input = keyPress;
cout << input << " is: " << keyPress << endl;
switch ( keyPress )
{
case 97 :
// Process for keypress = a
// Note On: 144, 60, 90
message.push_back( 144 );
message.push_back( 60 );
message.push_back( 90 );
midiout->sendMessage( &message );
break;
case 115 :
// Process for keypress = s
// Note Off: 128, 60, 90
message.push_back( 128 );
message.push_back( 60 );
message.push_back( 90 );
midiout->sendMessage( &message );
break;
case 27 :
// Process for keypress = esc
done = true;
break;
}
message.clear();
keyPress = NULL;
}
}
catch(RtError &error) {
error.printMessage();
exit( EXIT_FAILURE );
}
cleanup:
delete midiout;
return 0;
}
I tried sending control signals in the same manner as above but this time with control values in the message bytes in place of the note-on or note-off values.
When ableton live is running, I press a key to send a signal but the app locks up and doesn't return to the start of the while loop to receive input from the next keypress.
edit: I've just noticed that even the above code (which usually runs fine) freezes when ableton live is running and I press a key.
further edit: I downloaded a really neat app called MIDI Monitor, which can monitor MIDI data being transferred: http://obds.free.fr/midimon -- my MIDI controller device has two ports -> one for MIDI and one for control. When I'm monitoring control, I can send midi signals and vice versa. However, if, for example, I'm monitoring control and I try to send some CC type data the program locks. Could this be a device driver problem? –
Does anyone know what is going wrong here?
Just one comment - your exception handling is a little weird.
I'd wrap the whole code (initialization and all) in a try/catch(RtError &err) block, and lose most of the other try/catch blocks.
In particular, I don't know what your catch(char * str) stuff will achieve, and you have no catch at all if openPort() throws.
First of all, try sending a different CC and mapping it to some arbitrary control in Ableton, just to see if it's working. The volume controls you are trying to alter behave slightly differently than regular CC's. Specifically, you should check out the MIDI organization's recommended practice for incrementing/decrementing controllers (note that 0x60 == 96), namely when they write:
This parameter uses MSB and LSB separately, with MSB adjusting sensitivity in semitones and LSB adjusting sensitivity in cents. Some manufacturers may even ignore adjustments to the LSB.