How does count become 5 here? - c++

I am learning the use of get() and put() in c++. I have the following two doubts:
As we are in the while loop, why don't the characters get printed as soon as I enter them as there is a put right after the get?
Why does count has the value 5 instead of 4? When I hit the Enter key, I will exit the loop(at least that's what I understand). So we have count = 4 when the loop ends.
Here is the code:
#include<iostream>
using namespace std;
int main() {
int count = 0;
char ch;
cout << "Input text\n";
while(ch != '\n') {
cin.get(ch);
cout.put(ch);
count++;
}
cout << endl << count;
return 0;
}
Any kind of help is really appreciated. Please consider me a beginner in C++. Thanks.

The loop first enters cin.get() and does not continue until you enter all your 4 characters. It has to have a new line to continue. After you enter all your 4 characters, the loop continues and reads the characters one by one.
The value of count is 5 because it also gets incremented when you enter the new line. The new line is also a character. Your input is not abcd but abcd\n. And after it completes that last iteration, it checks the condition and sees that the last character is a new line and this is when it terminates.

Related

C++ store string sentences from user input into a vector

I am a beginner at C++ and currently learning vectors. Here is a simple code where program gets the user input and stores it in a vector then proceed to print the stored values from each element:
int main(){
vector<string> myVector;
string myInput;
int n;
cin>>n;
cin.ignore(numeric_limits<streamsize>::max(),'\n');
for(int i = 1; i <= n;i++){
cout<<"loop count: "<<i<<endl; //added for checking the current loop
getline(cin, myInput);
cin.ignore(numeric_limits<streamsize>::max(),'\n');
myVector.push_back(myInput);
}
for(unsigned int j = 0;j < myVector.size(); j++){
cout<<myVector[j]<<endl;
}
return 0;
}
but when I run my code, during the user string input, it lets me enter two strings before finally going to the next loop. the program only prints out the first entered string for each loop though. So my questions are:
1) What is the reason behind this? Why does user need to enter two strings before going to next loop? Can someone explain to me.
2) how can this be fixed?
EDIT: Here are my sample inputs and the output:
input:
3
input loop count: 1
we are
the champions
input loop count: 2
no time
for losers
input loop count: 3
we are
the champions
output:
we are
no time
we are
The problem is the ignore call inside the loop.
The std::getline will silently eat up the trailing newline, but since you then call ignore you must enter a second line for ignore to be satisfied.
Simply remove the ignore call from the loop and it should work as you expect.
Did you try to put cin.clear(); cin.sync(); before getline function? cin and getline give you problems when you use them at the same time.

Why "keep_window_open()" doesn't wait for a character to be entered?

I'm new to programming, and I'm trying to learn C++ by myself, and I'm following "Programming principles and practice using C++".
I was trying to do an exercise that, after various other steps, asked me to
" ...change the body of the loop so that it reads just one double each time around. Define two variables to keep track of which is the smallest and which is the largest value you have seen so far. Each time through the loop write out the
value entered. If it’s the smallest so far, write the smallest so far after the number. If it is the largest so far, write the largest so far after the number".
I wrote the following code so far:
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
inline void keep_window_open() { cout<<"\nType a character to exit: "; char ch; cin>>ch; }
int main()
{
double val1 = 0, smallest = 0, largest = 0;
int flag = 0;
while (cin >>val1) {
if (val1=='|')
break;
else
cout <<val1 <<'\n';
if (flag==0) {
smallest = val1;
cout <<smallest <<" it's the smallest value so far.\n";
}
if (val1<smallest) {
smallest = val1;
cout <<smallest <<" it's the smallest value so far.\n"; }
else if (val1>largest) {
largest = val1;
cout <<largest <<" it's the largest value so far.\n"; }
++flag;
}
keep_window_open();
return 0;
}
My problem is that when I input a character, e.g. 'c', the program ends, although the program should end, hypothetically, only when I enter '|', and I get:
c
Type a character to exit:
Process returned 0 (0x0) execution time : ...
Press any key to continue.
and "keep_window_open()" doesn't wait for a character to be entered. I just can't understand what happens, and why. Does anyone have a clue?
Well, I think the problem is in the way you defined your loop expression.
Neither cin nor its operator ">>" return a true / false value that you can work with. They return an iStream object which could be a dubious translation to true or false via an automated casting that happens behind the curtains. They will however return null when the input cannot be set inside your variable like in the case of trying to put 'c' into a double, and null translates into false.
What I suggest for you is to create a simple while(true) loop and when you get the "|" character from the user(as a string) you break the loop. until then the loop continues. then inside the loop parse your value and work on it according to your logic(minimum / maximum)
Problem
while (cin >>val1) reads input into a double. If you input something that cannot be read as a double like "|" then this will fail and cause your loop to exit.
You then try to read more input while cin is in an error state.
Solution
Call cin.clear() to first clear any error flags and then cin.ignore(1000, '\n') to throw away anything left hanging in the input stream.
inline void keep_window_open()
{
cout << "\nType a character to exit: ";
char ch;
cin.clear();
cin.ignore(1000, '\n');
cin >> ch;
}
Note
if (val1=='|')
break;
This code will never be true because if you try to input the pipe character your while loop will fall through before ever getting to it.

C++: Tracking iterations in code (after n iteration do x) / User input

I had a question in regards to a beginner assignment I was working on. The initial assignment requires me to make a program that asks the user to enter any number other than 5 until the user enters 5. If they enter 5 the program will alert them saying they input 5.
The next part of the assignment requires me to make a condition where after 10 iterations or 10 inputs of a non 5 value, the program messages the user and exits the program.
I finished the first part but had trouble with the second part. I searched stackoverflow and found something about the "get" function, but I'm not sure how to implement it correctly. How would I track the number of inputs or iterations and make a condition to where after n number of successful iterations the program exits?
Also , how would I make a condition to where if the user inputs a character instead of an integer the program warns the user and exits?
Thanks for the help. Here is the code I have written so far.
// This program works, however, if user inputs a character or a very large number
//then the program malfunctions.
// Learn more about the get function.
#include <iostream>
using namespace std;
int main()
{
int inpt;
cout << "Please input any number other than 5.\n";
cin >> inpt;
while (inpt != 5)
{
cout << "Please input another number other than 5.\n";
cin >> inpt;
}
if (inpt = 5)
{
cout << "Hey! You weren't supposed to enter 5!";
}
return 0;
}
you need to add a counter
int count = 0;
increment it each time round the loop
cout << "Please input another number other than 5.\n";
cin >> inpt;
count++;
and stop if the count gets too big
if(count>10) break;
you could also change your while condition
Note
if(inpt = 5) doesnt do what you think, you mean inpt == 5

while loop and getchar()

I have the simple program below that I wrote for a college course. I know it doesn't really do anything, but it's just an assignment for a course.
The part that I can't figure out, is why doesn't the outer loop work?
The user needs to press '1' to continue, and any other key the program exits.
However, it still doesn't continue if the user presses '1' and instead exits anyway.
I tried adding a cin.clear() before cin >> repeat, but that doesn't work.
I also tried playing around with cin.ignore(), but that didn't seem to help either.
Any ideas?
Thanks
int main()
{
int repeat = '1';
stack<char> cstr;
char c;
while (repeat == '1')
{
cout << "Enter in a name: ";
while (cin.get(c) && c != '\n')
{
cstr.push(c);
}
cout << "\n Enter another name? 1 = Continue, any other key to exit the program";
cin >> repeat;
repeat = getchar();
}
}
There is nothing at all wrong with your code. It seems to be working fine for me.
EDIT: Sorry it doesn't work until you remove the getchar. Forgot to mention that. Simple way of finding out the error is to just display the value of the variable repeat to see what the value is and where it is going wrong.
Screenshot to show you that your codes work
Everything seems to be working fine. I would like to comment on your program structure though. For small programs like this it's ok but always best to practice the logical way. For questions like this you should implement the do while loop instead of the while loop so that it goes in without checking and then accepts the user input and checks with the post condition. Example below.
char repeat;
do
{
//Your codes in here
}while (repeat == '1');
It is more logical to use this method instead unless your question specifies you to use while loop. Anyhow hope this helps.
Run this . it will solve your problem somehow repeat=getchar was making repeat=10.
int main()
{
char repeat = '1';
stack<char> cstr;
char c;
while (repeat == '1')
{
cout << "Enter in a name: ";
cin.ignore();
while (cin.get(c) && c != '\n')
{
cstr.push(c);
}
cout << "\nEnter another name ? \nPress 1 to Continue : ";
cin >> repeat;
cout << endl;
}
system("pause");
}
The line cin >> repeat is tring to read an integer from the keyboard because repeat is a variable of type int. However, you are verifying if the integer read from the keyboard is equal to 49 (the ASCII code for the character '1'), which is not what you want. A solution would be to replace the line
int repeat = '1';
with
int repeat = 1;
and also replace
while (repeat == '1')
with
while (repeat == 1)
because then you are comparing the integer read from the keyboard with the integer 1 (rather than the character '1'). Also, at the end of the loop you read input from the keyboard and store it in repeat but then you immediately read input again and store that value in repeat, replacing its previous value. To solve this, replace the line
repeat = getchar();
with
getchar();
and that should do it.
cin >> repeat;
it reads repeat as int. (1 is not equal '1')
repeat = getchar();
It reads int code of special char '\n' - symbol end of line.
You must use
char repeat = '1';
Or write
int repeat = 1;
and not use getchar()

String to ascii function

I actually wrote a function to convert string into ascii values.
However I managed to confuse my self and don't understand why my own code works.
here it is:
void convertToString()
{
char redo;
int letter;
int length;
do {
cout<< "How long is your word \n";
cin >> length;
cout << "Type in the letter values \n";
for (int x = 0; x < length; x++) {
cin >> letter;
cout << char (letter);
}
cout << "\n To enter another word hit R" << endl;
cin >> redo;
} while (redo == 'R');
}
In the terminal I can type in all the ASCII values I want with out changing line, however I though this would cause a problem, anyways my question is, is hitting the enter button the same as hitting space? if not i dont understand how my code is able to print out the chars since i write it all in one line...Does it assign the interger "letter" a new value everytime there is a space?
Please help/explain
This is to expand a bit on what Igor said in his comment and to give a little example.
As Igor said, istream::operator>>(&int) will read non-whitespace. This means for each call on the operator, it scans along the input stream (what you typed in) for non-whitespace and reads until the next whitespace again. The next call will pick up where you left off. So, entering a space or a newline is exactly the same for this situation where you're taking in an int.
You can verify this with a simple bit of code that scans until EOF:
#include <iostream>
int main()
{
int number;
while (std::cin >> number)
{
std::cout << number << std::endl;
}
return 0;
}
This will wait for user entry to be complete (pressing enter), but print a new line for each integer in your input as separated by whitespace. So "1 2 3 4" will print each of those numbers on separate lines, regardless of if you separate them with spaces, tabs, or newlines.