I am new to programming, started with C++ quite recently and I use CLion IDE.
I need to solve something, but I am not sure how exactly and I need your help with a basic C++ console program.
if the user enters a ten-digit number and the fifth number is one, the output should be this word - "zadochno".
if the user enters a ten-digit number and the fifth number is two, the output should be this word - "redovno".
The user is expected to enter 2101162235 or similar.
In any case, the fifth element should be either 1 or 2.
Examples:
Option 1: input> 2101162235 -> output string "zadochno"
Option 2: input> 2101262235 -> output string "redovno"
I am able to only partially create the program:
#include<iostream>
int number;
cout << "Please, enter number: ";
cin > number;
//I believe there should be an if statement or for loop here:
if(){
}
Can you please help me?
You can take the input from the user as std::string and then check if the element at index 4 is 1 or 2 as shown below:
#include <iostream>
#include <string>
int main()
{
std::string input;
//take input from user
std::getline(std::cin, input);
//check if the 5th letter(at index 4 since indexing starts with 0) is '1' or '2'
if(input.at(4) == '1')
{
std::cout<< "zadochno"<<std::endl;
}
else if(input.at(4) == '2')
{
std::cout << "redovno"<<std::endl;
}
//this below shown for loop is optional. If you're sure that the user input contains only digits then you can skip/remove this for loop.
for(int i = 0; i < input.size(); ++i)
{
//check if the all the characters are digits of a number
if(std::isdigit(input[i]))
{
;//std::cout<<"yes digit";
}
else
{
std::cout<<"Please enter a valid number"<<std::endl;
}
}
return 0;
}
The output of the above program can be seen here.
Assuming the user does enter a 10 digit number (ie you don't need to check if they enter eg "foo" or "bar3000"), you can do the following:
Read the input as a std::string, not as int. User input is a string of characters always. Only if you need it you can get it converted to an integer. You do not need it as int. The n-th character of a std::string called user_input is user_input[n]. You just need to check whether the character in the middle is either '1' or '2'.
If you do need to check that the user did enter digits, you could use std::isdigit.
Related
I am currently trying to write a program at school involving a random number generator for rolling a dice. I have written the code successfully, but I am trying to improve it so that the size of the dice and the number the user is trying to roll can be chosen by the user.
I have written code that does this, and I have also added code that repeats the request for input if the wrong value (ie not one of the dice sizes offered or trying to roll a number outside the range of the dice) or input type (ie var instead of int) is entered. However, if a floating point number is entered, and the number to the left of the floating point is in the correct range of values, it is using that number.
For example:
int size = 0;
cout << "Please choose the size of the dice to roll (6, 12 or 20): ";
cin >> size;
while (size != 6 && size != 12 && size != 20 || !cin)
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Invalid number entered. Choose the size of the dice to roll (6, 12 or 20): ";
cin >> size;
}
This will correctly ask to repeat the input if any letters or any numbers that aren't 6, 12 or 20 are entered, but if 20.125 (or any floating point number that is 6.- 12.- or 20.-) is entered it will take the number and move on to the next bit of code. This also happens if I enter a valid number followed by letters (ie 6f).
I tried modifying the condition of the while loop to:
while (size != 6 && size != 12 && size != 20 || !(cin >> size))
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Invalid number entered. Choose the size of the dice to roll (6, 12 or 20): ";
cin >> size;
}
And that fixes the problem, and it asks me for another input if I enter 12.5 or 20R etc, but then when I enter a correct input (6, 12 or 20) it just takes me to a new line in the debugger without moving to the next line of code. If I then enter a correct input again, it reads it at takes me to the next line of code.
I don't quite understand why one works 99% how I want it to with one error, and the other fixes that error but then gives me another one.
Thanks in advance, any advice guidance is much appreciated!
The way cin >> some_int_variable will interpret the input is character by character, until it stops making sense as an int. For instance, when it encounters . or f, cin is done reading that int.
If you want a different behavior, you will have to implement it yourself. Specifically, how do you stop processing one input, and starts processing the next?
cin >> some_int_variable will stop when it is no longer a valid it, cin >> some_std_string_variable will stop when it encounters an white-space character (new lines included). How about your problem? How do you want to separate one input from the next?
If white-space is a sensible approach, you can do so:
std::string word;
std::cin >> word;
int value;
bool error = false;
try {
size_t pos;
value = std::stoi(word, &pos);
// Was the full string used to build the int?
if(pos != word.size()) error = true;
} catch(std::logic_error&) {
error = true;
}
if(error) { /* something went wrong */ }
See the docs for std::stoi().
You could read a float, assign it to an integer variable and then compare the two. Something along these lines:
int integerSize;
float floatSize;
cin >> floatSize;
integerSize = floatSize; //Your program will perform a cast from float to integer, it will essentially truncate whatever appears after the floating point.
if (integerSize != floatSize) //Your program will now perform a cast from integer to float in order to compare the two, but if floatSize was not a whole number, this comparison should return false.
{
//code to ask for another value
}
That being said, floats (and doubles and long doubles) do experience rounding errors, so as another user suggested, the safest bet is to read a string and parse it yourself, or using a built-in function like std::stoi() (only for integers) and std::stof() (for floats).
template<typename T>
T typed_read_line(const std::string& prompt)
{
T result{};
std::string l;
std::cout << prompt << ":";
while (std::getline(std::cin, l)) {
std::istringstream line{l};
line >> result >> std::ws;
if (line.eof()) break;
//line contains more then expected
std::cout << "Again: " << prompt << ":";
}
return result;
}
https://godbolt.org/z/dfYKe3
Or version with extra validation or v3.
I am sure this will seem very novice to many on here but I am currently trying to learn C++ and have an in depth full understanding to apply my knowledge in the real world.
The Problem Description:
Write a program that graphically depicts an integer’s magnitude by using asterisk, creating a
histogram. Hint: The inner loop handles the printing of the asterisk and the outer loop handles
exciting until zero is entered. Make sure you don’t accept negative numbers.
Sample run:
Enter a positive integer (0 to quit): 5
*****
Enter a positive integer (0 to quit): 8
********
Enter a positive integer (0 to quit): -5
Enter a positive integer (0 to quit): -10
Enter a positive integer (0 to quit): 15
***************
Enter a positive integer (0 to quit): 0
Good Bye!
My Current Code (I know this isn't right by any means, but helps demonstrate my thinking, I know you need to use a nested loop to answer this properly.):
#include <iostream>
using namespace std;
int main()
{
int ast; //Number of asterisk wanted to be displayed
char asts='*'; //Actual display coressponding to asterisk
cout<<"Enter a positive integar, (0 to quit)"<<endl;
cin>>ast;
while(ast!=0)
{
if(ast>0) // Ensuring no negative integars are entered
{
asts=ast;
cout<<asts<<endl;
cout<<endl;
}
else //Display if negative or other invalid data is entered
cout<<"Invalid Data, negative values are not accepted, try a positive integar or 0 to quit"<<endl;
cout<<"Do you want to continue? If so, enter another integar (0 to quit)"<<endl;
cin>>ast;
}
cout<<"Thank you for using the program."<<endl;
return(0);
}
Thank you for the help ahead of time!
-Colin
The basic idea is (with pseudo-code):
get number of asterisks
while number is not zero:
if number is negative:
output error message
else:
do number times:
output *
output newline
get number of asterisks
Your nested loops there are while number is not zero and do number times.
However, one of the earliest skills you should learn as a developer is to properly assign tasks to specific pieces of code (methods, functions, libraries and so on). In particular, it's a good idea to modularise your code so that each piece has a well defined purpose, then build the "upper" layers out of those pieces.
To that end, this is how I would approach the problem. First, define the functions that would be useful in this case.
Start with getAsterCount() which is responsible for asking the user how many asterisks they want and verifying that it's valid (asking again and again, until it is). For example:
#include <iostream>
int getAsterCount() {
// Until we get valid response.
for(;;) {
int count;
// Get value, checking for error, forcing exit if so.
std::cout << "Enter the number of asterisks, zero to exit: ";
if (! (std::cin >> count)) {
std::cout << "*** ERROR: could not read number\n";
return 0;
}
// Any non-negative value is allaowed.
if (count >= 0) {
return count;
}
std::cout << "That was less than zero, try again.\n";
}
}
Once that's in place, you never have to worry again about the user providing invalid information for this program, since this function will capture it (and you can call it from anywhere, as shown in the main() function below.
Next, provide a function that will actually output the asterisks, based on the count you now have:
void outputAster(int count) {
// Simple loop for asterisks then new line.
for (int i = 0; i < count; ++i) {
std::cout << '*';
}
std::cout << '\n';
}
With that in hand, your main code becomes the conceptually much simpler:
int main() {
int count = getAsterCount();
while (count > 0) {
outputAster(count);
count = getAsterCount();
}
std::cout << "Thank you for using the program. Now get off my lawn.\n";
}
Right now you are trying to do:
asts=ast;
Which doesn't make much sense, as this will only assign the entered integer to asts.
To print the magnitude in * you need to loop from 0 to the inputted integer and print out an asterix every time:
for(int i = 0; i < ast; i++) {
std::cout << "*";
}
std::cout << "\n";
Output:
Enter a positive integar, (0 to quit)
5
*****
Do you want to continue? If so, enter another integar (0 to quit)
3
***
Do you want to continue? If so, enter another integar (0 to quit)
5
*****
Do you want to continue? If so, enter another integar (0 to quit)
0
I like a somewhat different approach, without a loop.
char asts[] = “*********\n”;
After checking that the input value is in range, just write out the tail of the string:
std::cout << (asts + 9 - ast);
My assignment is to take test grades of students in a class room and return the highest, lowest, and the average. I am currently debugging for error that could be entered by the user. I have successfully fixed issues when the user inputs characters for the decimal test score values. What I'm having trouble with is if the user inputs "4k" the program excepts the 4 as a valid input but still gives the error when the program shouldn't approve the score as a valid input but should error and prompt for only numeral values.
I'll provide an output example
heres the code segment:
for (int i = 0; i < students; i++)
{
cout << "Please enter a score: " << flush;
cin >> array[i];
do{
if(cin.fail())
{
cin.clear();
cout<<"Error, that's not a decimal number. Please reenter: ";
std::cin.ignore(numeric_limits<streamsize>::max(), '\n' );
cin >> array[i];
}
}while(cin.fail());
}
Sample output error::
How many students are in class? 3
Please enter 3 scores
- - - - - - - - - - -
Please enter a score: jkl
Error, that's not a decimal number. Please reenter: jkl
Error, that's not a decimal number. Please reenter: 4k
Please enter a score: Error, that's not a decimal number. Please reenter: 0
Please enter a score: 3
4
0
3
The worstest score in the class is: 0
The bestest score in the class is: 4
The average score is: 2.33333
Note: Based on your tags, I'm going to assume that you are using c++11. If not this answer wont work.
Using what you already have, try the following method to get the user input:
#include <iostream>
#include <string>
#include <limits>
#include <stdexcept>
double getValidInput()
{
// Some variables for controlling how this works
std::string user_input ; // Used to store input
bool bad_input(true) ; // Set to true when the input is good
double value(0.0) ; // Value that will be returned
size_t pos(0) ; // Tells us when all of user_input was useable
cout << "Please enter a score: " << flush ;
cin >> user_input;
// Now do the thing
while (bad_input) {
try {
// Note that this may return an invalid string->double conversion
value = std::stod(user_input, &pos) ;
} catch (std::invalid_argument & err) {
// The input isnt a number that can be converted
// to a double
pos = 0 ;
}
// If the entire string was converted then all is good!
if (pos == user_input.size()){
bad_input = false ;
} else {
cout<<"Error, that's not a decimal number. Please reenter: ";
std::cin.ignore(numeric_limits<streamsize>::max(), '\n' );
cin >> user_input ;
}
}
return value ;
}
Ok, so what does all of this do? Lets start with
try {
// Note that this may return an invalid string->double conversion
value = std::stod(user_input, &pos) ;
} catch (std::invalid_argument & err) {
// The input isnt a number that can be converted
// to a double
pos = 0 ;
}
The user provides you with a string and you want to get a number from it (I'm assuming of type double). The above code is going to try to convert the user's input from a string to a double using std::stod(). Note that we also pass another variable pos which stores the length of the string that was able to be converted to a double.
Lets check your inputs:
In the case of your first input jkl a straight conversion to double cant be done. As a result std::stod throws an exception of type std::invalid_argument. The code catches that and sets pos=0. The following if statement notes that the length of the input string is longer than pos, so not all of the input was able to be converted, and the user has to try again.
In the case of your second input, 4k, std::stod can convert the string to a double up to the k, but at that point it stops. No exception is thrown, but pos is now one character smaller than the string, and again the user has to try again.
Now, you would insert this into your for-loop like so:
for (int i = 0; i < students; i++)
{
array[i] = getValidInput() ;
}
Hope that helps!
First of all thanks for answering and helping out...
Now i was making a program to let the user enter any number... and then use the program to point out the total number of 4's in the the number entered and i have now encountered a problem..
This is my first post here so please excuse me if i make any mistakes..
The Code
int main()
{
int T,i,j,l;
char N,p[10];
cin>>T;
while(T--) //The number of times a user can enter a new number
{
cout<<"\nEnter Numbers\n";
l=0;i=0;
do
{
N=getch(); //getch is used so that the enter key need not be pressed and the
//number looks like a whole and also so the each number is
//individually stored
p[i]=N; //here the number entered is stored in p
cout<<N; //to display the number obviously
l++;i++;
}while(N!=' '); //Now here between '' something has to be present so that the loop
//terminates as soon as the enter key is pressed right now as soon
//as the spacebar is hit the loop will terminate.
cout<<"\n";
j=0;
for(i=0;i<l;i++) //using l so that the loop runs accordingly
{
if(p[i]=='4')
{
j++; //for couting the number of 4's
}
cout<<p[i]<<"\n"; //wont be needing in the final program but here cout is just
// to check the output
}
cout<<"\n THERE ARE "<<j<<" FOURS\n";
}
}
Please not that i already have a solution for my program so please DO NOT provide a different code using some different logic... i really need this very same program to work.i know that this program can be made to work using string length but here i want the loop to terminate after the enter key is pressed.
Well if you want to stop getting input when the user presses enter instead of space you need to test against '\r', '\n' or '\r\n' depending on what OS you are using. That said you really should be using standard C++ if you are going to use C++. You could easily make your code like:
#include <iostream>
#include <string>
#include <algorithm>
int main()
{
int loops;
std::cout << "How many numbers to check: ";
std::cin >> loops;
std::cin.get(); // eat newline
for (int i = 0; i < loops; i++)
{
std::string numbers;
std::cout << "Enter numbers and press enter: ";
std::getline(std::cin, numbers);
auto numberOf4s = std::count(numbers.begin(), numbers.end(), '4');
std::cout << "Number of 4's entered: " << numberOf4s << std::endl;
}
return 0;
}
Live Example
You can to see check if N is equal to '\r'. So your while loop looks like
do
{
N=getch(); //getch is used so that the enter key need not be pressed and the
//number looks like a whole and also so the each number is
//individually stored
p[i]=N; //here the number entered is stored in p
cout<<N; //to display the number obviously
l++;i++;
}while(N!='\r');
I was wondering if there was anyways of stopping letters being entered for an integer. Here is the code which I have been using in my int main.
do
{
cout << "Player 1 please enter the value of the row you would like to take ";
cin >> row;
}while (row != 0 && row != 1 && row != 2 && row != 3);
My problem with this code is that if the user enters a letter it creates a never ending loop. Any help would be much appreciated.
Standard library doesn't provide anything that would filter characters that are entered through standard input. I believe you could use libraries like curses to do that.
What you can do, though, is check whether input suceeded. operator>> for int will set the stream's state to failbit if it couldn't extract an integer (for example, when it encountered an 'a' or something like that. You can use extraction operators in boolean context, something like this:
cout << "Player 1 please enter the value of the row you would like to take ";
while (!(cin >> row) || (row < 0 || row > 3)) {
cout << "Invalid input, try again!\n";
// clear the error flags and discard the contents,
// so we can try again
cin.clear();
cin.ignore(std:numeric_limits<std::streamsize>::max(), '\n');
}
Note that if you enter for example 1abc, the read will succesfuly read 1 and leave the abc in the stream. This might not be a desired behaviour. If you wish to treat that as an error you can say
if ((cin >> std::ws).peek() != EOF) { /* there's more input waiting */ }
and act accordingly, or just unconditionaly ignore everything from the stream once you've got a value.
Get characters one at a time and only add the number characters to the string. Use
cin.get();
in a loop.