I have a program like this:
#include <iostream>
#include <conio.h>
using namespace std;
int main ()
{
for (int i = 0; i < 10; i++)
{
cout << int (_getch ()) << endl;
}
_getch ();
return 0;
}
If I press keys like digits, alphabets and Enter, a single integer is displayed (per iteration of the loop). However, if I press keys like Insert, Delete, or the arrows, two integers are displayed at once.
Why does this behaviour occur?
From _getch()
When reading a function key or an arrow key, each function must be called twice;
The first call returns 0 (for F1-F10) or 0xE0 (224) (for others) , and the second call returns the actual key code.
Related
I'm stuck on trying to add quantities to this list when it returns the output. It is essentially a list entered by the user that starts with a quantity and is followed by a word. It is then supposed to output the same list but in alphabetical order. I currently have it alphabetized but the numbers that the user enters on the same line, are returned on a separate line from the word when returned in alphabetical order. I know I am prompted to use parallel arrays but have no clue how to incorporate them into this. Nobody has been able to reply to me but I know it is do-able. Thank you all in advance!!
#include <iostream>
#include <string>
#include <iomanip>
#include "functions.h"
#include <algorithm>
#include <set>
using namespace std;
void print(const string& item)
{
cout << item << endl;
}
int main(void)
{
const int MAX_LENGTH = 256;
string items [MAX_LENGTH];
int quantities [ MAX_LENGTH];
string itemChoice;
string qtyChoice;
int numItems= 0;
int randomArray[MAX_SIZE];
{
set<string> sortedItems;
cout << " (type \"exit\" twice to exit, now press enter twice to begin listing your shopping list.): ";
getline (cin, qtyChoice);
getline(cin, itemChoice);
for (int i = 1; ; i++)
{
string itemChoice;
string wholeOrder;
cout << i << ". ";
cin >> itemChoice;
cin >> qtyChoice; // this is how I got it to intake #'s
//getline (cin, qtyChoice);// putting these here actually allow both items to be on one line!! but it leaves awkward spaces.
//getline(cin, itemChoice);
//getline (cin, qtyChoice);
if (itemChoice == "exit")
{
break;
}
sortedItems.insert(qtyChoice);
sortedItems.insert (itemChoice);
//sortedItems.insert(itemChoice);
}
for_each(sortedItems.begin(), sortedItems.end(), &print);
return 0;
}
this is my code and this is what happens as output
(type "exit"to exit, now press enter twice to begin listing your list.):
1. 3828 eijsd
2. 38238 shd
3. 382 hsdid
4. exit
382
38238
3828
eijsd
hsdid
shd
You make no distinction between quantities and words in your set, so they are treated as the same kind of thing, with no connections between them. To preserve the connection, you need a more complicated data structure.
Using parallel arrays is one possibility, but the overhead is a pain. A simpler approach than a pair of arrays would be an array of pairs -- better yet a set of pairs, as you already know that sets provide easy sorting. (A map would also work.)
set< pair<string,string> > sortedItems;
Storing both the word and the quantity in the pair retains the relationship between them. I'll leave it to you to fill in the rest of the details.
#include "stdafx.h"
#include "iostream"
#include "thread"
#include "conio.h"
#include "windows.h"
using namespace std;
void incrm();
void charget();
void main() {
thread count(incrm);
thread getcin(charget);
count.join();
getcin.join();
cin.get();
}
void incrm() {
int j = 0; // used to increment and output
while (true) {
cout << "\r" << j; // outputs 1,2,3,4... and so on
j++;
Sleep(150);
}
cout << endl;
}
void charget() {
while (true) {
int i = getch(); // gets value of char
cout << "\r\nCHAR: " << i; // and here is the problem...!
}
}
So I wanted this program to output a number in the first line, which increments without stopping and if you hit any key it should cout the value of that key in a secound line, so i wanted it to output something like this->
45
CHAR: 97
and after you have hit a key the incrementing number should stay in the first line. If you hit several keys the second cout should be overwritten, but this doesnt seem to work for me, my output looks like this if i hit several keys->
10
12AR: 97
20AR: 96
My problem is that my first cout (the incrementing number) overwrites my second (or my second my first I don't really know) and then this countinues for every line! :(
I suggest you to use windows function called gotoxy(). You can apply this using
SetConsoleCursorPosition();
this function is availible in windows.h library.
It is possible to read more about it here:
Link
I have a problem with do while loop which is escaped when user hit some key. I increase some value by 1 every time it loops. But when I'm printing this value (after every key press) the value is getting printed two times.
The code is as below:
#include <iostream>
#include <windows.h>
#include <conio.h>
using namespace std;
int main () {
int x = 0;
char asd;
do {
x++;
asd = getch();
cout << x << " ";
} while(asd!=27);
system("pause");
return 0;
}
I need to check if the key has been pressed, but I dont know how to fix this issue with double printing every time key has been pressed.
Some help?
This is because getch() reads not only the character you do input, but also the new line feed.
You do actually write some_character and \n into the input stream. Both are characters and both are read.
You need to ignore rest of the stream, after the 1st character read.
Another thing it might be is that some keys generate two character codes "0 or 0xE0, and the second call returns the actual key code".
You can see what is really happening with something like this:
#include <iostream>
#include <windows.h>
#include <conio.h>
using namespace std;
int main () {
int x = 0;
char asd;
do {
x++;
asd = getch();
cout << "Character code read: " << int(asd)
<< ", character count:" << x << "\n";
} while(asd!=27);
}
This will print actual key codes of what is read, so you will see what is going on.
So I'm a beginner programmer... and I can't figure out what the problem is in this bit of code I'm writing for a text adventure. All I want it do At the moment is let the user enter a command, and then it converts it to ALLCAPS and prints that out. It should output this:
What shall I do?
pie
Your raw command was: PIE
But instead, it outputs this:
What shall I do?
pie
PIE
...and then it freezes. Here's the code:
#include <iostream>
#include <string>
#include <cctype>
#include <cstring>
#include <vector>
using namespace std;
void command_case();
string userIn;
string raw_command;
int x = 0;
int main()
{
while(raw_command != "QUIT")
{
cout << "What shall I do?\n";
cin >> userIn;
command_case();
cout << "Your raw command was: " << raw_command << endl;
}
return 0;
}
void command_case()
{
char command[userIn.size()+1];
strcpy(command, userIn.c_str());
while(x < userIn.size()+1)
{
if(islower(command[x]))
{
command[x] = toupper(command[x]);
cout << command[x];
x++;
}
else if(isupper(command[x]))
{
cout << command[x];
x++;
}
}
raw_command = command;
}
I think it may be a problem with the while loop in void command_case(), but I can't figure out exactly what that problem is. I'd appreciate any advice you can give me.
One too much:
while(x < userIn.size()+1)
The problem is with the x variable in the command_case() function.
When x becomes 3 (and "command[x] points to the null character at the end of "pie")
neither islower(command[x]) or isupper(command[x]) are true.
Neither section of the if statement executes, so x stays at 3 forever.
Since "userIn.size()+1" is 4, and x never reaches 4, the loop never exits.
A possible solution is remove the "x++" from both sections of the if statement, and have a single "x++" after the if statement. This will increment x during every loop regardless of what character "command[x]" points to.
You could easily do something like
void command_case()
{
for(int i =0; i<userIn.size(); i++)
{
userIn[i] = toupper(userIn[i]);
}
}
then cout<<userIn in the main
You should remove all cout calls from command_case() function. In fact the whole if-branch in the function is useless and you could just replace it with the following:
command[x]=toupper(command[x]);
For the simplicity you could replace the whole command_case() function with (just remember to #include <algorithm>):
std::transform(userIn.begin(), userIn.end(), userIn.begin(), toupper);
I have only been doing this for 3 months and currently at a stand still. I am not sure what I'm doing wrong. I would appreciate any help pointing me in the right direction. I am not asking for anyone to do my homework for me. I am supposed to write a program to accept from the user one line of input and then count and output the number of lowercase letters. This is what I have so far but it doesn't do what it is supposed to do.
#include <fstream>
#include <iostream>
#include <cctype>
#include <string>
using namespace std;
int main(){
char text;
int count = 0;
cout << " Enter one line of text: ";
do
{
cin.get(text);
while(text!='\n')
{
if(islower(text))
count++;
}
} while(text!='\n');
cout << count << "\n";
}
The problem was with the input: you input distinct characters, but whitespace would be skipped.
You can use std::getline to get a line of input at once:
#include <algorithm>
#include <iostream>
#include <cctype>
#include <string>
using namespace std;
int main()
{
cout << " Enter one line of text: ";
string s;
if(getline(cin, s))
{
size_t count = count_if(s.begin(), s.end(),
[](unsigned char ch) { return islower(ch); });
cout << count << "\n";
}
}
You create an infinite loop:
while (text != '\n') {
...
}
will continue forever if text (somewhat of a misnomer for a character) ever happens to be something different than '\n'. As a general guideline, whenever you create a loop you need to verify that the body of the loop somehow makes progress towards the end of the loop and that the end of the loop is reached (unless, of course, you intend to create an infinite lop) You probably just want to get rid of this while (...) and just keep the body.
Note that the outer loop should have two conditions to terminate:
It should terminate if you reach the end of a line.
It should terminate if you reach the end of the input: This isn't necessarily terminated by a newline.
If I were to write the loop it would look something like this:
for (std::istreambuf_iterator<char> it(std::cin), end; it != end && *it != '\n'; ++it) {
// do something with the `char` obtained from `*it`
}
It is also worth noting that you need to make sure that a positive value is passed to islower() (or any of the other functions from <cctype>): There are systems where char is signed and, e.g., the ü in my name would convert into a negative value, causing undefined behavior when calling islower('ü'). The way to avoid this problem is to convert the char into an unsigned char before passing it to the <cctype> functions: the bit pattern of static_cast<unsigned char>(c) is identical to the bit pattern of c (assuming that c is of type char).
Sticking with the original approach of a while-loop reading a char, the basic loop would look something like this:
while (std::cin.get(text) && text != '\n') {
if (std::islower(std::static_cast<unsigned char>(text))) {
++count;
}
}
In general, I have found that do ... while-loops rarely don't survive into production code and this isn't an exception: You only want to enter the loop if the char could successfully be read. Since a newline won't be a lower case letter, it can be put into the condition directly as well. For ASCII character std::islower(text) would work but to make the code solid, I have added a cast to unsigned char to make sure things won't break. Finally, the C++ idiom to increment variables is, ironically, preincrement, i.e. ++count rather than count++. The primary use is that preincrement is more efficient if the type to which it is applied is not entirely trivial. Since C++ uses lots of iterators which are incremented, it is conventional to use preincrement.