How to use getch() without waiting for input? - c++

for (;;)
{
cout << "You are playing for:" << playtime << "seconds." << endl;
cout << "You have " << bytes << " bytes." << endl;
cout << "You are compiling " << bps << " bytes per second." << endl;
cout << "Press a to buy assembler monkey (produces 1 byte per second)/(cost 10 bytes)" << endl;
switch(getch())
{
case 'a': bytes = bytes - 10; bps++; break;
}
bytes = bytes + bps;
playtime++;
Sleep(1000);
system("cls");
}
Let's say that's my incremental game. I want refresh my game after 1 second. How can I make getch() to wait for input without stopping all other stuff?

Use kbhit() function to detect if a key was pressed :)
something like:
for (;;)
{
cout << "You are playing for:" << playtime << "seconds." << endl;
cout << "You have " << bytes << " bytes." << endl;
cout << "You are compiling " << bps << " bytes per second." << endl;
cout << "Press a to buy assembler monkey (produces 1 byte per second)/(cost 10 bytes)" << endl;
if(kbhit()){ //is true when a key was pressed
char c = getch(); //capture the key code and insert into c
switch(c)
{
case 'a': bytes = bytes - 10; bps++; break;
}
}
bytes = bytes + bps;
playtime++;
Sleep(1000);
system("cls");
}

You could use another thread, to get the user input.
The for (;;) is unnecessary, instead you should use while (true).
#include <Windows.h>
#include <iostream>
#include <conio.h>
using namespace std;
DWORD WINAPI SpeedThread(LPVOID lpParam);
int main ()
{
int playtime = 0,
bytes = 0,
bps = 1;
bool bKeyPressed = false;
CreateThread( NULL, 0, SpeedThread, &bKeyPressed, 0, NULL);
while (true)
{
cout << "You are playing for:" << playtime << "seconds." << endl;
cout << "You have " << bytes << " bytes." << endl;
cout << "You are compiling " << bps << " bytes per second." << endl;
cout << "Press a to buy assembler monkey (produces 1 byte per second)/(cost 10 bytes)" << endl;
if (bKeyPressed && bytes >= 10)
{
bytes -= 10;
bps++;
bKeyPressed = false;
}
bytes = bytes + bps;
playtime++;
Sleep(1000);
system("cls");
}
}
DWORD WINAPI SpeedThread (LPVOID lpParam)
{
bool * bKeyPressed = (bool *) lpParam;
while (true)
{
if (_getch () == 'a')
*bKeyPressed = true;
}
}

What worked for me is not to use getch() but instead use scanf().
In order to stop scanf from stopping you have to use :
scanf("%c \n",example);
Keep in mind, that example is a pointer (char* example;)

Related

C++ Strings getting printed as hex, when that isnt the purpose

im working on a project for school where we are supposed to create a Contact book.
I stumbled on to a problem where my program prints out strings as hexa symbols, i have never encountered this before and have no idea on how to combat it.
The strings are getting printed out on the terminal from an array.
#include <iostream>
#include <string>
using namespace std;
const int unikapersoner = 75;
string I_namn[unikapersoner];
string T_Nummer[unikapersoner];
void addcontact() {
char Fullname[50];
char TelefonNummer[50];
cin.ignore();
cout << "Ange det fullständiga namnet du vill spara till kontaktboken.. "
<< endl;
cin.getline(Fullname, 50);
cout << "Ange telefonnummeret till personen som du vill spara.. " << endl;
cin.getline(TelefonNummer, 50);
for(int i = 0; i < unikapersoner; i++) {
if(T_Nummer[i] == "\0") { // Letar efter tom index.
I_namn[i] = Fullname;
T_Nummer[i] = TelefonNummer;
break;
}
}
}
void listALLcontacts() {
cout << "/Kontakter/." << endl;
cout << "=================================" << endl;
int nr = 0;
for(int i = 0; i < unikapersoner; i++) {
if(T_Nummer[i] != "\0") {
nr++;
cout << "#" << nr << " " << I_namn << " " << T_Nummer << endl;
cout << "- - - - - - - - -" << endl;
}
}
cout << "=================================" << endl;
if(nr == 0) {
cout << "Du har inga kontakter i din telefonbok..";
}
}
int main() {
int terminalval;
system("CLS");
do {
cout << "Din telefonbok!" << endl;
cout << "1 : Ange ny Kontakt" << endl;
cout << "2 : Se nuvarande Kontakter" << endl;
cout << "3 : Uppdatera kontakt" << endl;
cout << "4 : Radera kontakt" << endl;
cout << "5 : Avsluta" << endl;
cout << "Ange ditt val.." << endl;
cin >> terminalval;
switch(terminalval) {
case 1:
addcontact();
break;
case 2:
listALLcontacts();
break;
case 3:
updatecontacts();
break;
case 4:
deletecontact();
break;
default:
cout << "Är ett felaktigt kommando! " << endl;
}
} while(terminalval != 5);
}
Some outputs could for example be "#1 0x123123fb123 0x213g2134z13"
I would as always appreciate all the help i could get!
Thank you.
You are printing the addresses of the arrays I_namn and T_Nummer in the function listALLcontacts here:
cout << "#" << nr << " " << I_namn << " " << T_Nummer << endl;
You should use the index, i, to print the found entry:
cout << "#" << nr << " " << I_namn[i] << " " << T_Nummer[i] << endl;
A note unrelated to the problem you asked about:
You do a few comparisons like this
if(T_Nummer[i] == "\0")
which isn't needed. "\0" is actually 2 chars long, consisting of the \0 you've put there and then a terminating \0, so just do
if(T_Nummer[i] == "")
or even better:
if(T_Nummer[i].empty())

How to make the console print something by pressing a key like F2 or F3

UPDATE! I figured out how to find the keys and defined them in my code. The problem is I don't know how to make it so the console prints the selection and it gives u time to press a key. Then it gets plugged into to the switch which prints the current gun depending on the key pressed. I am also using windows 10. I also have encountered another problem I want it to print out Guns first then ask for an input (this part works fine) but then instead of just printing the attachments, it prints out both attachments and the humanized level.
#include <iostream>
#include <istream>
#include <fstream>
#include <string.h>
#include <conio.h>
#include <string>
using namespace std;
#define KEY_F1 17
#define KEY_F2 18
#define KEY_F3 19
#define KEY_F4 20
#define KEY_F5 21
#define KEY_F6 22
#define KEY_F7 23
#define KEY_F8 24
#define KEY_F9 25
#define KEY_F10 26
#define KEY_F11 27
#define KEY_F12 28
#define KEY_N7 103
#define KEY_N8 104
#define KEY_N9 105
int main() {
char gun;
char att;
char hum;
char key = _getch();
int value = key;
cout << "" << endl;
cout << "Developed by ! CaptaiN#9999" << endl;
cout << "" << endl;
cout << "Guns" << endl;
cout << "" << endl;
cout << "[F1] AK" << endl;
cout << "[F2] MP5" << endl;
cout << "[F3] M2" << endl;
cout << "[F4] SAR" << endl;
cout << "[F5] Tommy" << endl;
cout << "[F6] Custom" << endl;
cin >> gun;
cout << "" << endl;
cout << "Attachnments" << endl;
cout << "" << endl;
cout << "[F7] Holosight" << endl;
cout << "[F8] Simplesight" << endl;
cout << "[F9] Silencer" << endl;
cout << "[F10] 8x Zoom Scope" << endl;
cout << "[F11] 16x Zoom Scope" << endl;
cout << "[F12] No Attachment" << endl;
cin >> att;
cout << "" << endl;
cout << "Humanize Levels" << endl;
cout << "" << endl;
cout << "[Numpad 7] 3 (HIGH)" << endl;
cout << "[Numpad 8] 2 (MODERATE)" << endl;
cout << "[Numpad 9] 1 (LOW)" << endl;
cin >> hum;
//system("CLS");
while (value != KEY_X) {
switch (_getch()) {
case KEY_F1:
cout << "Current Gun: AK" << endl;
break;
case KEY_F2:
cout << "Current Gun: MP5" << endl;
break;
case KEY_F3:
cout << "Current Gun: M2" << endl;
break;
case KEY_F4:
cout << "Current Gun: SAR" << endl;
break;
case KEY_F5:
cout << "Current Gun: Tommy" << endl;
break;
case KEY_F6:
cout << "Current Gun: Custom" << endl;
break;
}
switch (att) {
case KEY_F7:
cout << "Current Attachment: Holosight" << endl;
break;
case KEY_F8:
cout << "Current Attachment: Simplesight" << endl;
break;
case KEY_F9:
cout << "Current Attachment: Silencer" << endl;
break;
case KEY_F10:
cout << "Current Attachment: 8x Zoom Scope" << endl;
break;
case KEY_F11:
cout << "Current Attachment: 16x Zoom Scope" << endl;
break;
case KEY_F12:
cout << "Current Attachment: None" << endl;
break;
}
switch (hum) {
case KEY_N7:
cout << "Humanized Level: 3" << endl;
break;
case KEY_N8:
cout << "Humanized Level: 2" << endl;
break;
case KEY_N9:
cout << "Humanized Level: 1" << endl;
break;
}
}
}
I think pm100's answer is a perfectly acceptable way to do this, but the resulting code from such a technique would be fragile and dependent on the platform (because there's no standard representation as he mentions).
If that's fine with you, use his answer. A more portable way to do this would be to use a terminal control library, the most common one being curses
(it's technically a c library FYI). There are two main implementations: pdcurses mainly for Windows and ncurses for Mac and Linux. I won't go over set up here since that will mostly depend on the library, but if you want to make it cross-platform you can use cmake but that isn't super easy (because you have to handle pdcurses and ncurses separately).
Regardless of curses implementation, a minimal example of capturing the F1-F12 keys is below:
#ifdef _WIN32
#include <pdcurses.h>
#else
#include <ncurses.h>
#endif
int main()
{
initscr();
cbreak();
noecho();
keypad(stdscr, TRUE);
while (true) {
int ch = getch();
if (ch >= KEY_F(1) && ch <= KEY_F(12)) {
printw("F* key pressed\n");
}
}
endwin();
return 0;
}
for additional details on the library I recommend this programming guide.
as a side note, you might want to consider something like std::map to map your keys to std::string as it would be a little less verbose than using switch statements.
there is not standard representation of function keys. So start out by working out what chars arrive at your app when Fn is pressed. Quite likely that its more than one char.
on linux you can do
cat > fn.bin
od -tx2 fn.bin
this shows what chars are generated by Fn
Okay, so since your question has basically changed, I'll put a new answer to address it. I see you've gone with the platform-specific option. Luckily, I'm on Windows 10 as well, so I can still help.
First things first, I'm having some difficulty with the keycodes you listed in your defines - I'm getting a null character (0) and then some other character like ; (59) for F1 and > (60) for F2. For F11 and F12 I get a completely different set of characters (as you can see in my code). I'm not really sure why we'd be getting different results, maybe something weird with encodings? Would you mind stating where you found the character codes listed in the snippet? For the rest of my answer, I'll just use what I'm getting (sorry, I don't know what else to do).
Here is the code that will achieve what I think you want - it gets the user's initial "loadout" in the first part of the code. In the main loop it allows you to enter a new weapon, and just prints the attachment selected earlier. I didn't add handling for the number pad keys, but the technique should be the same if you want to do it.
#include <iostream>
#include <string>
#include <conio.h>
#include <array>
#include <map>
// define the parts for all F* keys
using multipart_t = std::array<int, 2>;
constexpr multipart_t KEY_F1 = { 0, 59 };
constexpr multipart_t KEY_F2{ 0, 60 };
constexpr multipart_t KEY_F3{ 0, 61 };
constexpr multipart_t KEY_F4{ 0, 62 };
constexpr multipart_t KEY_F5{ 0, 63 };
constexpr multipart_t KEY_F6{ 0, 64 };
constexpr multipart_t KEY_F7{ 0, 65 };
constexpr multipart_t KEY_F8{ 0, 66 };
constexpr multipart_t KEY_F9{ 0, 67 };
constexpr multipart_t KEY_F10{ 0, 68 };
constexpr multipart_t KEY_F11 = { 224, 133 };
constexpr multipart_t KEY_F12 = { 224, 134 };
// map those arrays to the corresponding ints
const std::map<multipart_t, int> F_KEY_TO_INT{
{ KEY_F1, 1 },
{ KEY_F2, 2 },
{ KEY_F3, 3 },
{ KEY_F4, 4 },
{ KEY_F5, 5 },
{ KEY_F6, 6 },
{ KEY_F7, 7 },
{ KEY_F8, 8 },
{ KEY_F9, 9 },
{ KEY_F10, 10 },
{ KEY_F11, 11 },
{ KEY_F12, 12 }
};
// add a utility function that returns the pressed key as an int of 1-12 (for F1-F12 keys)
int fGetch() {
// TODO: add checking to check it actually is an F* key instead of just failing silently (REALLY BAD)
multipart_t keys;
keys[0] = _getch();
keys[1] = _getch();
return F_KEY_TO_INT.find(keys)->second;
}
int main() {
std::cout << "" << '\n';
std::cout << "Developed by ! CaptaiN#9999" << '\n';
std::cout << "" << '\n';
std::cout << "Guns" << '\n';
std::cout << "" << '\n';
std::cout << "[F1] AK" << '\n';
std::cout << "[F2] MP5" << '\n';
std::cout << "[F3] M2" << '\n';
std::cout << "[F4] SAR" << '\n';
std::cout << "[F5] Tommy" << '\n';
std::cout << "[F6] Custom" << '\n';
// TODO: valid character checking (for all 3)
int gun(fGetch());
std::cout << "" << '\n';
std::cout << "Attachnments" << '\n';
std::cout << "" << '\n';
std::cout << "[F7] Holosight" << '\n';
std::cout << "[F8] Simplesight" << '\n';
std::cout << "[F9] Silencer" << '\n';
std::cout << "[F10] 8x Zoom Scope" << '\n';
std::cout << "[F11] 16x Zoom Scope" << '\n';
std::cout << "[F12] No Attachment" << '\n';
int att(fGetch());
// I'll leave you to handle function keys, it should be basically the same
/*std::cout << "" << '\n';
std::cout << "Humanize Levels" << '\n';
std::cout << "" << '\n';
std::cout << "[Numpad 7] 3 (HIGH)" << '\n';
std::cout << "[Numpad 8] 2 (MODERATE)" << '\n';
std::cout << "[Numpad 9] 1 (LOW)" << '\n';
std::cin >> hum;*/
system("CLS");
std::cout << "main loop start" << '\n';
int value = 0;
while (value != 'x') {
value = fGetch();
switch (value) {
case 1:
std::cout << "Current Gun: AK" << '\n';
break;
case 2:
std::cout << "Current Gun: MP5" << '\n';
break;
case 3:
std::cout << "Current Gun: M2" << '\n';
break;
case 4:
std::cout << "Current Gun: SAR" << '\n';
break;
case 5:
std::cout << "Current Gun: Tommy" << '\n';
break;
case 6:
std::cout << "Current Gun: Custom" << '\n';
break;
}
switch (att) {
case 7:
std::cout << "Current Attachment: Holosight" << '\n';
break;
case 8:
std::cout << "Current Attachment: Simplesight" << '\n';
break;
case 9:
std::cout << "Current Attachment: Silencer" << '\n';
break;
case 10:
std::cout << "Current Attachment: 8x Zoom Scope" << '\n';
break;
case 1:
std::cout << "Current Attachment: 16x Zoom Scope" << '\n';
break;
case 12:
std::cout << "Current Attachment: None" << '\n';
break;
}
// TODO
/*switch (hum) {
case KEY_N7:
std::cout << "Humanized Level: 3" << '\n';
break;
case KEY_N8:
std::cout << "Humanized Level: 2" << '\n';
break;
case KEY_N9:
std::cout << "Humanized Level: 1" << '\n';
break;
}*/
}
}
In the code, I've added places for you to improve upon mine (it's mostly checking for a user typing the wrong key at the wrong time).
The actual input was handled by putting the multiple characters into an array and using a map to map that to the appropriate int for that F1-F12 key. Please note that the function currently has next to no error checking.

can countdown work simultaneously with the program in c++

I am currently making a quiz program. And I created a countdown, but as c++ does actions line by line I am getting what I want. I want countdown work simultaneously with the tests.
here is the one part of my program
void QUIZ::OOP2()
{
system("cls");
QUIZ("OOP2");
int oop2_time = 100;
for (int i = oop2_time; oop2_time >= 0; i--)
{
cout << "\t\t\tQuestions of OOP2\n\n";
line();
cout << "1. Switch selection structure can be used to represent any kind of if-else selection structure? \n";
line();
cout << " a) True b) False \n";
CorrectB(var);
if (oop2_time == 100)
{
cout << "You have the remaining" << oop2_time << "seconds \n" << endl;
Sleep(40000);
}
if (oop2_time == 60)
{
cout << "You have the remaining" << oop2_time << "seconds \n" << endl;
Sleep(30000);
}
if (oop2_time == 30)
{
cout << "You have the remaining" << oop2_time << "seconds \n" << endl;
Sleep(15000);
}
if (oop2_time == 15)
{
cout << "You have the remaining" << oop2_time << "seconds \n" << endl;
Sleep(10000);
}
if (oop2_time == 5)
{
cout << "You have the remaining" << oop2_time << "seconds \n" << endl;
Sleep(5000);
cout << "\nTime is out\n";
goback();
intro();
}
result("OOP2");
goback();
}
}
Without using multi-threading or std::chrono but just your base code, here's a code snippet. I have used recursive function and a time resolution of 1 second. The countdown can also be terminated prematurely in the main by setting stop = true; :
#include <iostream>
#include <windows.h>
void wait(double sec, bool& stop)
{
std::cout <<"Time remaining "<< sec << " sec\n";
if (stop || sec <= 0) return;
Sleep(1000);
wait(sec-1, stop);
}
int main()
{
bool stop = false;
wait(5, stop);
}

Libusb - ubuntu - Psoc5. libusb_open_device_with_vid_pid return 0

I am working on a power engineering project on 4th semester, and programming isn't my strong side. I've been working on using libusb for communication between a PSoC 5 and a Linux terminal program written in C++. The terminal code is:
The problem is that libusb_open_device_with_vid_pid(NULL, 0x1111, 0x2222) returns 0 every time, even though the device is recognized by the Linux OS. OS is Ubuntu if that is relevant.
#include <iostream>
#include "libusb-1.0/libusb.h"
#include "usb.h"
#include <time.h>
using namespace std;
union USB_DATA
{
unsigned char USB_ARRAY[1200];
int DirectionOfPower;
int menu;
float Voltage;
float Current;
float Temperature;
float PowerFactor;
float DistortionPowerFactor;
float Amplitude_Of_Harmonics[1001];
float Regulate_To;
};
union USB_DATA USB_;
/*
void error(string s, int err)
{
cout << s " ERROR: " << libusb_error_name(err) << endl;
exit(err);
}
*/
int main()
{
int transfer_size;
int err;
float Reg_To;
// Device Handle
libusb_device_handle* dev;
// Initialize libusb with default context
libusb_init(NULL);
// Open Device VID = 0x1111, PID = 0x2222 with the default libusb context
dev = libusb_open_device_with_vid_pid( NULL, 0x1111, 0x2222 );
// If device is null, we didn't find it
/*
if (dev == NULL)
{
cout << "Device not found, exiting." << endl;
return -1;
}
int k = 0;
while (dev == NULL)
{
cout << "Device not found, trying again." << " " << k << endl;
//sleep(1);
k = k+1;
}
*/
// Claim interface 0 on the device. Here we te the operation system that wewan this device
libusb_claim_interface(dev, 0);
libusb_detach_kernel_driver(dev, 0);
// Set alternate setting 0 on interface 0
libusb_set_interface_alt_setting(dev, 0, 0);
while(true)
{
cout << "Welcome to Spaendingsregulering!" << endl;
cout << endl;
cout << "MENU" << endl;
cout << "Indtast nummer for navigation" << endl;
cout << "1. Indsaet driftsparametre " << endl;
cout << "2. Analyser harmoniske " << endl;
cout << "3. Fremvis data " << endl;
while(true)
{
cin >> USB_.menu;
if(cin.good())
break;
cin.clear();
}
/*
err = libusb_bulk_transfer(dev, 0x02, USB_.USB_ARRAY, sizeof(union USB_), &transfer_size, 1000);
if( err )
error( "Bulk OUT Transfer Failed!", err);
err = libusb_bulk_transfer(dev, 0x81, USB_.USB_ARRAY, sizeof(union USB_), &transfer_size, 1000);
if( err )
error( "Bulk IN Transfer Failed!", err);
*/
if(USB_.menu == 1)
while(true)
{
cout << "Indsaet oensket spaending" << endl;
cout << "Indtast 999 for at vende tilbage til hovedmenuen" << endl;
cin >> Reg_To;
cout << endl;
if(Reg_To == 999)
{
break;
}
USB_.Regulate_To = Reg_To;
cout << "=======================" << endl;
cout << "Saetter oensket spaending til:" << " " << USB_.Regulate_To << "V" << endl;
cout << "=======================" << endl;
cout << endl;
cout << "Vender tilbage til hovedmenu" << endl;
cout << "..." << endl;
cout << endl;
if(cin.good())
break;
cin.clear();
}
}
}
libusb_open_device_with_vid_pid combines finding and opening and doesn't return an error code. If you are sure the device is there, have you checked you have the rights to read/write to it ? You can also increase the verbosity of error messages.
– Leiaz
Thanks! that did it!. I forgot to use sudo.. rookie mistake – Çağrı Esen

Playing a sound in a MIDI Callback function

I got this little piece of code which is working fine for now. However I want to play a sound in the callback function but I read in the MSDN pages:
"Applications should not call any multimedia functions from inside the callback function, as doing so can cause a deadlock. Other system functions can safely be called from the callback".
I'm quite new to programming and my question is: How can I work around this and still be able to play sounds when a MIDI-key is hit.
#include<iostream>
#include<cstdlib>
#include<windows.h>
#include<Mmsystem.h>
#include<stdio.h>
using namespace std;
void CALLBACK midiCallback(HMIDIIN handle, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
{
switch (uMsg)
{
case MIM_OPEN:
cout << "-----OPENED.-----" << endl;
break;
case MIM_CLOSE:
cout << "-----EVERYTHING IS CLOSING.-----" << endl;
break;
case MIM_DATA:
cout << "-----APPARENTLY THERE I5 DATA.-----" << endl;
break;
case MIM_LONGDATA:
cout << "-----LONGDATA'D.-----" << endl;
break;
case MIM_ERROR:
cout << "-----ERROR.-----" << endl;
break;
case MIM_LONGERROR:
cout << "-----LONGERROR. EVEN WORSE.-----" << endl;
break;
}
cout << "dwInstance is " << dwInstance << endl;
cout << "Handle is " << handle << endl;
cout << "dwParam1 is " << dwParam1 << endl; //dwParam1 is the bytes of the MIDI Message packed into an unsigned long
cout << "dwParam1_hiword is " << HIWORD(dwParam1) << endl; //velocity
cout << "dwParam1_loword is " << LOWORD(dwParam1) << endl; //keyID
cout << "dwParam2 is " << dwParam2 << endl; //dwParam2 is the timestamp of key press
cout << "uMsg is " << uMsg << endl;
cout << "-----" << endl;
}
void MidiThing() {
MIDIINCAPS mic;
unsigned long result;
HMIDIIN inHandle;
unsigned long iNumDevs, i;
iNumDevs = midiInGetNumDevs(); /* Get the number of MIDI In devices in this computer */
/* Go through all of those devices, displaying their names */
for (i = 0; i < iNumDevs; i++)
{
/* Get info about the next device */
if (!midiInGetDevCaps(i, &mic, sizeof(MIDIINCAPS)))
{
/* Display its Device ID and name */
cout << "Device ID [" << i << "]: " << mic.szPname << endl;
}
}
cout << endl;
// Open the default MIDI In device. (DevID 0)
result = midiInOpen(&inHandle, 0, (DWORD)midiCallback, 0, CALLBACK_FUNCTION);
if (result != MMSYSERR_NOERROR) {
cout << "midiInOpen() failed...rv= " << result << endl;
}
else
{
midiInStart(inHandle);
}
cout << endl;
cout << "Press \"ESC\" to quit." << endl;
while (1) {
if (GetAsyncKeyState(VK_ESCAPE))
{
break;
cout << "exit=true." << endl;
}
Sleep(100);
}
midiInStop(inHandle);
midiInReset(inHandle);
midiInClose(inHandle);
cout << endl;
cout << inHandle << " was the MIDIIN handle." << endl;
cout << endl;
cout << "MIDI is closed now." << endl;
}
int main(int argc, char *argv[])
{
MidiThing();
cout << "Exit is success." << endl;
return EXIT_SUCCESS;
}
Wake up another thread from the callback.