I've been working on a calculator and I am very close to getting it working, but I need to find a way to have the amount of numbers and operators that the user puts in to be up to the user. This is a simpler test version of what I have so far that I need to apply this to. I left out a few things but this is the exact part of the code I need to apply it to. The user should be able to input any amount of numbers and operands as long as it is under 20 of each. I don't want to stick to a rigid form of input, like cin >> numIn[n]; cin >> operator1[n], because then you would HAVE to end with an operator, for example.
#include <iostream>
float numIn[20];
char operator1[20];
int main(){
int n = 0;
while (n < 20){
std::cin >> numIn[n] >> operator1[n];
switch (operator1[n]){
case '+':
std::cout << numIn[n] + numIn[n];
break;
default:
std::cout << "does not work";
}
}
}
I edited this question to be more focused and clear. I added the part of the text above about how I need to have a 'fluid' way of input. If this doesn't make it more clear I don't know what does.
Use getline to get a whole line of input from the user.
Then use that string to construct a stringstream, which you can use your >> on to extract the numbers and single-char operators. But now you get an error when you try to read past the end of the original string. It knows you are done, because it has the complete input committed before it started to read, unlike an always-open terminal where the user could always type more.
use std::cin >> numIn[n] and std::cin >> operator1 [n]
as #Ivan suggested in the replies
Related
cout << "Would you like to make another transaction? (y/n)" << endl;
cin >> repeat_transaction;
static_cast<char>(repeat_transaction);
while (repeat_transaction != 'y' && repeat_transaction != 'n')
{
cout << "Invalid selection: Please enter y or n";
cin >> repeat_transaction;
static_cast<char>(repeat_transaction);
}
During the Invalid selection loop, I once accidentally pressed "mn". I noticed the console read out Invalid selection..., So, it did in fact finish and re-enter the while loop. However, after this the console terminated the program. If you enter a single character 'a' or 'y' or 'n' it acts just as it should. Ending or not ending. This was before I attempted to use static_cast to force the truncation of the user input.
Since you managed to get this program to compile I can only assume that repeat_transaction was specified as a char and not a std::string.
When you use cin to get a character it only gets one character but it doesn't flush the buffer. I believe you understand this issue since you wrote This was before I attempted to use static_cast to force the truncation of the user input. . You can attempt to use cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); instead of static_cast<char>(repeat_transaction); after each call to cin >> repeat_transaction; . There are downsides to this. If you enter 'mn' it will work as expected. It reads the m which is not y or n and then flushes the extra characters until it finds end of line \n. If you do nm, n will match and the m will be thrown away. So in that case it will accept nm as valid and exit the loop.
There are other ways that may be easier and give you the effect closer to what you are looking for. Instead of reading a character at a time you can read an entire line into a string using getline (See the C++ documentation for more information). You can then check if the length of the string is not equal to 1 character. If it's not length 1 then it is invalid input. If it is 1 then you want to check for y and n. Although basic (and not overly complex) this code would do a reasonable job:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string repeat_transaction;
cout << "Would you like to make another transaction? (y/n)" << endl;
getline(cin, repeat_transaction);
while (repeat_transaction.length() != 1 || (repeat_transaction != "y" && repeat_transaction != "n"))
{
cout << "Invalid selection: Please enter y or n";
getline(cin, repeat_transaction);
}
return 0;
}
I said reasonable job since one deficiency you might see is that you want to trim white spaces from the beginning and end. If someone enters n or y with a space or tab in front it will be seen as invalid (whitespace at the end would be similar). This may not be an issue for you, but I thought I would mention it.
On a final note, you may have noticed I used using namespace std;. I did so to match what was in the original question. However, this is normally considered bad practice and should be avoided. These StackOverflow answers try to explain the issues. It is better to not do it and prepend all standard library references with std::. For example string would be std::string, cin would be std::cin etc.
Hi I'm having trouble validating this string to be all decimals, even if I type in 9999 it still tell me my if statement comes out false. I think it's a typo but I don't know where.
cout<<"Enter a very large number"<<endl;
cin>>In1; //inputs a string
for(int i=0; 0<In1.length();i++){ //the loop that goes thru each index
if (!(isdigit(In1[i]))){ //validates each index
//tells the user to try again
cout<<"You did not enter a valid input, please try again"<<endl;
In1="";
cin>>In1;
i=0;//starts the loop over if reached
}
}
I keep receiving the "You did not enter a valid input, please try again" regardless of whether I type it right or wrong.
for(int i=0; 0<In1.length();i++){
See what you did? Change to
for(int i=0; i<In1.length();i++)
In your loop condition you need to compare i with In1.length().
You might want to change
0<In1.length()
to
i<In1.length()
Using
#include<algorithm>
if ( std::find_not_if( in1.begin(), in1.end(), isdigit ) != in1.end() ){ ...
might have prevented this unfortunate incident, and is also quite clear on the intent. The dual _not/!= muddles it slightly but still.
There are quite a few convenience algorithms, replacing common uses for simple for- statements. Most of them are on the form
do_this( where_to_start, where_to_end, do_this_operation )
There is usually nothing special or dramatic with these function, they apply the operation to each element in the start-end sequence.
You have find, count, copy, and generate to mention a few. Their purpose is to clarify the intent of your for-statement. You can find a complete list at http://en.cppreference.com/w/cpp/algorithm
You will almost certainly find that, over time, you become more adept at seperating different parts of code into the functionality that they each provide. Making debugging and later modification considerably easier.
It also makes, as Captain Giraffe points out, the intent of the code considerably more clear - something that can only make reading the code easier & quicker.
I've not used std::find_not_if, opting instead to use the method that you've chosen (based on the assumption that the important thing is knowing how to get the right answer, as opposed to simply supplying the right answer - well, that and me not knowing of find_not_if's existence :grin:) You'll see that I've chucked it into it's own function, which I call from main. The function also only performs a single task - that of checking the validity of the string. Any attempt to prompt the user for this text, re-prompt in the case of error and finally, take action on the correct input is the sole responsibility of the code that calls isValidNumericalString - there's no reason you couldn't throw those functions into their own functions, as opposed to having a single, large body of main.
#include <iostream>
using namespace std;
// returns true if all characters in string are numerical (0-9)
bool isValidNumericalString(string inputString)
{
int i, n = inputString.length();
for (i=0; i<n; i++)
if ( !isdigit(inputString[i]) )
return false;
return true;
}
int main()
{
string In1;
cout << "Enter a very large number (digits 0-9 only. 10e1 is unacceptable): ";
cin >> In1;
while (!isValidNumericalString(In1))
{
cout << "You did not enter a valid input, please try again :p" << endl;
cout << "Enter a very large number (digits 0-9 only. 10e1 is unacceptable): ";
cin >> In1;
}
cout << "Congratulations - '" << In1 << "' is a valid string representation of a number" << endl;
return 0;
}
I have a simple little script I am coding, and I am trying to not allow people to enter a string, or if they do make it revert to the beginning of the function again. Here's the input code I have:
int main()
{
cout << "Input your first number" << endl;
cin >> a;
cout << "Input your second number" << endl;
cin >> b;
}
The rest of the code beyond this part works just fine for what's going on, although if a string is entered here it obviously doesn't work.
Any help would be appreciated.
You may find this post useful,
How to check if input is numeric in C++
Basically you can check the input, whether it is numeric value or not. After checking whether the given input is numbers, then you can add a while loop in main to ask user to repeat if input is not a valid number.
Every input is a string. If you want to know if a entered string can convert to a number, you have to read in a string and try to convert it yourself (eg with strol).
An alternative would be to check if the reading from cin failed, but personally i don't like it because cin.fail() covers more error situations than just a failed type conversion.
There's a library function may help,you can check it after input:
int isdigit(char c);
Tips:
1.You should include such files :
# include <ctype.h>
2.If c in 0 ~ 9 ,return 1 ; else return 0.
How do you check to see if the user didn't input anything at a cin command and simply pressed enter?
When reading from std::cin, it's preferable not to use the stream extraction operator >> as this can have all sorts of nasty side effects. For example, if you have this code:
std::string name;
std::cin >> name;
And I enter John Doe, then the line to read from cin will just hold the value John, leaving Doe behind to be read by some future read operation. Similarly, if I were to write:
int myInteger;
std::cin >> myInteger;
And I then type in John Doe, then cin will enter an error state and will refuse to do any future read operations until you explicitly clear its error state and flush the characters that caused the error.
A better way to do user input is to use std::getline to read characters from the keyboard until the user hits enter. For example:
std::string name;
getline(std::cin, name); // getline doesn't need the std:: prefix here because C++ has ADL.
ADL stands for argument-dependent lookup. Now, if I enter John Doe, the value of name will be John Doe and there won't be any data left around in cin. Moreover, this also lets you test if the user just hit enter:
std::string name;
getline(std::cin, name);
if (name.empty()) {
/* ... nothing entered ... */
}
The drawback of using this approach is that if you want to read in a formatted data line, an int or a double you'll have to parse the representation out of the string. I personally think this is worth it because it gives you a more fine-grained control of what to do if the user enters something invalid and "guards" cin from ever entering a fail state.
I teach a C++ programming course, and have some lecture notes about the streams library that goes into a fair amount of detail about how to read formatted data from cin in a safe way (mostly at the end of the chapter). I'm not sure how useful you'll find this, but in case it's helpful I thought I'd post the link.
Hope this helps!
cin will not continue with the program unless the user enters at least 1 character (enter doesn't count). If the user doesn't give ANY input, cin will just keep waiting for the user to give input and then press enter.
The Simple way >>
{
char X=0; // ASCII( 0 ) means a NULL value
cin>>X;
if(X==0 || X==10) // ASCII( 10 ) means ENTER
cout<<"User din't enter ANYTHING !! ";
}
But a simple problem is....
cin just won't allow you to move further without entering a character
by character here i mean a DIGIT or alphabet or special symbol , not space, enter null etc
Hope this solves your problem, if it doesn't, I'll be glad to help just let me know.
int main(){
string str[100];
std::cout<<"Hello how are you ? \n";
std::cin>>str;
if(str.length() > 0){
// If input is seen
}
else{
// If input is not seen
}
}
Any problem let me know.
I am new to C++ and am in a class. I am trying to finish the first project and so far I have everything working correctly, however, I need the user to input a number to select their level, and would like to validate that it is a number, and that the number isn't too large.
while(levelChoose > 10 || isalpha(levelChoose))
{
cout << "That is not a valid level" << endl;
cout << "Choose another level:";
cin >> levelChoose;
}
That is the loop I made, and it sometimes works. If I type in 11 it prints the error, and lets me choose another level. However if the number is large, or is any alpha character it floods the screen with the couts, and the loop won't end, and I have to force exit. Why does it sometimes stop at the cin and wait for user input, and sometimes not? Thanks for the help!
This is an annoying problem with cin (and istreams in general). cin is type safe so if you give it the wrong type it will fail. As you said a really large number or non-number input it gets stuck in an infinite loop. This is because those are incompatible with whatever type levelChoose may be. cin fails but the buffer is still filled with what you typed so cin keeps trying to read it. You end up in an infinite loop.
To fix this, you need to clear the fail bit and ignore all the characters in the buffer. The code below should do this (although I haven't tested it):
while(levelChoose > 10 || isalpha(levelChoose))
{
cout << "That is not a valid level" << endl;
cout << "Choose another level:";
if(!(cin >> levelChoose))
{
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
}
Edit: numeric_limits<> is located in the limits include:
#include<limits>
From your description, it seems likely (nearly certain) that levelChose is some sort of numeric type, probably an integer.
When you use operator>> to read a number, anything that couldn't be part of a number (e.g., most letters) will be left in the input buffer. What's happening is that you're trying to read the number, it's failing and leaving the non-digit in the buffer, printing out an error message, then trying to read exactly the same non-digit from the buffer again.
Generally, when an input like this fails, you want to do something like ignoring everything in the input buffer up to the next new-line.
levelChoose appears to be an integer type of some form (int, long, whatever).
It's not valid to input a character into an integer directly like that. The input fails, but leaves the character in the incoming buffer, so it's still there when the loop comes around again.
Here's a related question: Good input validation loop using cin - C++
I suspect the part while(levelChoose > 10..... This does not restrict level to less than 10 (assuming greater than 10 is a large number in your context). Instead it probably should be while(levelChoose < 10...
To check that an expression is not too large, the following could be a possibility to validate (brain compiled code!!)
const unsigned int MAX = 1000;
unsigned int x;
cin >> x;
while(x < MAX){}