How to verify all correct input digits C++ - c++

I have the following code, this can check if the input is an integer; however, if something like '5o' is input it still flows through, can someone help me make sure all the digits input into x are correct, thank you!
#include <iostream>
using namespace std;
int main() {
cout << "enter x please: ";
int x;
cin >> x;
while (cin.fail()) {
cout << "sorry wrong input, try again: ";
cin.clear();
cin.ignore();
cin >> x;
}
cout << "correct input!";
return 0;
}

Read an entire line at once as a string and validate:
#include <iostream>
#include <string>
#include <algorithm>
#include <cstdio>
#include <cctype>
int main()
{
std::printf("Enter x: ");
std::string line;
while (true)
{
if (!std::getline(std::cin, line))
{
std::puts("Stream failed."); // Not much we can do
return -1;
}
if (std::all_of(line.cbegin(), line.cend(), std::isdigit))
break;
else
std::printf("Input is not a number. Try again: ");
}
int const x = std::stoi(line);
std::printf("x = %d\n", x);
}

Related

"noskipws" works but doesn't stop in c++

I am trying to write a program that checks if a phrase is a palindrome or not, and in case nothing is entered or just whitespace, it should print out "empty".
At first, the user should type in the number of phrases that they are going to enter (e.g. 3), and then the phrases that are to be checked.
It works just fine, but when my first input is empty, it prints out "empty" again and again without asking for another phrase.
#include <iostream>
#include <string>
#include <iomanip>
#include <math.h>
using namespace std;
int main() {
int N;
int isPalindromeCounter=0;
int counter = 0;
string inputString;
cin >> N;
cout << "\n";
while (counter<N){
counter++;
cin.ignore(100, '\n');
cin >> noskipws >> inputString;
if (inputString.length()==0){
cout <<"empty\n";
continue;
}
int left = 0;
int right = inputString.length()-1;
if (inputString.length()>20){
cout <<"error\n";
continue;
}
bool isPalindrome = true;
while (left<right){
if (inputString[left] != inputString[right]){
isPalindrome = false;
cout << "no\n";
break;
}
left++;
right--;
}
if (isPalindrome){
cout << "yes\n";
isPalindromeCounter++;
}
}
double percentage = double(isPalindromeCounter)/double(counter)*100;
if (trunc(percentage) != percentage){
cout << setprecision(5) << percentage;
}
else {cout << percentage << ".000" ;}
return 0;
}
What am I doing wrong ?
I expected that it should print "empty" once, and then ask for another input, but it prints "empty" for all the inputs.

Trying to make a loop to check the string for numbers only and negative numbers allowed in C++ im new to programming this is a class project

I'm trying to make a loop to check input strings for numbers only, and negative numbers are allowed. I'm new to programming, this is for a class project.
This code works, to an extent. When it shows the output, it does not show the first number, and does not allow - to be used. I cannot figure out where I'm going wrong in this.
#include "stdafx.h"
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
string userInput;
int i = 0;
bool checkInput(int);
int main()
{
do
{
cout << "Please enter a numeric value : ";
string userInput;
cin >> userInput[i];
}
while (!checkInput(userInput[i]));
system("pause");
return 0;
}
bool checkInput(int input)
{
string userInput;
int i;
cin >> userInput;
for (int i = 0; i < userInput.length(); i++)
if (isdigit(userInput[i]))
{
cout << "\nYour input " << userInput << " is a valid numeric input." << endl;
return true;
}
else
{
cout << "Please enter a valid numeric value: ";
cin >> userInput[i];
return false;
}
}
Your code doesn't work because you are not utilizing std::string correctly.
When main() prompts the user, it reads into a char of an empty std::string, which is undefined behavior. You should be reading into the std::string itself without calling its operator[] at all. operator>> has an overload for reading std::string values.
checkInput() is just all kinds of wrong. It takes an int as input instead of a std::string, but ignores that input and waits for the user to type in another string value. Then it loops through that string instead of the one read by main(), and only checks the 1st char before exiting. If the char is a digit, checkInput() returns true, and main() exits. Otherwise, checkInput() prompts the user to type in yet another char and then returns false, which then causes main() to prompt the user to type in yet another char. checkInput() does not actually loop through an entire string at all, and does no have any handling for the - character.
Try this instead:
#include "stdafx.h"
#include <iostream>
#include <string>
#include <cctype>
#include <limits>
using namespace std;
bool checkInput(const string &);
int main()
{
string userInput;
cout << "Please enter a numeric value : ";
do
{
cin >> userInput;
if (checkInput(userInput))
break;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Please enter a valid numeric value: ";
}
while (true);
cout << "\nYour input " << userInput << " is a valid numeric input." << endl;
system("pause");
return 0;
}
bool checkInput(const string &input)
{
if (input.empty())
return false;
string::size_type i = 0;
if (input[0] == '-')
{
++i;
if (i == input.length())
return false;
}
do
{
if (!isdigit(input[i]))
return false;
}
while (++i < input.length());
return true;
}
However, the best way to handle this situation is to simply not allow the user to enter non-integer values to begin with. operator>> has overloads for reading integer values, both signed and unsigned types. In this case, reading int values will suffice. Let cin do all of the input validation for you:
#include "stdafx.h"
#include <iostream>
#include <limits>
using namespace std;
int main()
{
int userInput;
cout << "Please enter a numeric value : ";
while (!(cin >> userInput))
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Please enter a valid numeric value: ";
}
cout << "\nYour input " << userInput << " is a valid numeric input." << endl;
system("pause");
return 0;
}

C++: How to solve a char bug in a do while loop?

Can you help me to solve this bug?
It is a game where you need to guess the hidden number. The problem is that when I enter a character that isn't an integer number, the program outputs a message infinitely,
Here is bug message if i enter a char
but I would like to make this program to output only message "You haven't entered a number, please try again".
Here is a normal execution
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
using namespace std;
main(){
int a,b;
char c;
START:
system("cls");
srand (time(NULL));
a = rand() % 100 + 1;
cout << "Guess The hidden Number Between 1 and 100" << endl;
do {
cout << endl<<" Enter Any Number : "; cin>>b;
if(b>100||b<1) cout<<" Try another number that is between 1 and 100!!!";
else {
if (b>a)
cout <<" =>Too Big";
else if (b<a)
cout <<" =>Too Small";
else if (b==a) {
cout<<" =>You've Guess It!!!"<<endl;
break;
}
}
}
while (b != a);
cout << endl << "Press 'q' to start. Press else to close ";
c = getch();
if (c=='q'||c=='Q') goto START;
}
Your code int b; cin >> b; will try to read integer and will fail if where is no integer in the stream. Fail bit of cin will be set, you can check it either with if(cin.fail()) {} or just if(cin) {}. So, you need to extract junk input from cin before the next read. You can reach this effect by actually reading anything from cin and then trying to convert it to an integer.
#include <iostream>
#include <string>
using namespace std;
int main() {
int b;
string s;
do {
cout << endl << "Enter Any Number: ";
getline(cin, s);
try {
b = stoi(s);
cout << "Your code goes here." << endl;
}
catch (invalid_argument& ex) {}
catch (out_of_range& ex) {}
} while (true);
}
Something like this
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
int main() {
int b;
char s[1];
do {
cout << endl << "Enter Any Number: ";
gets(s);
try {
b = atoi(s);
cout << "Your code goes here." << endl;
}
catch (invalid_argument& ex) {}
catch (out_of_range& ex) {}
} while (true);
}
What you are seeing is the stream breaking. When you do std::cin << intNum; with a non-integer input, the data types are non-compatible, so it doesn't know what to do. To "fix" the stream, you need to clear the stream of it's error state using std::cin.clear() then the standard practice is to ignore the rest of the line to avoid other invalid input. A code snippet would look something like this:
while(std::cin.fail())
{
std::cin.clear();
std::cin.ignore(1000000, '\n');
}
This will check if the stream is broken, clear the flag so it can take input again, then clear out the next 1000000 characters or to the next \n, whichever comes first.

Getting rid of white spaces (C++)

My code allows the user to input numbers, it sorts them, and outputs them in order.
Example input: 25,1,3-6
Example output: 1,3,4,5,6,25
However when the user inputs something like 2 5,1,3-6, and if there is a space in a case like 3 - 6, the program doesn't work.
I used cin>>ws; to try to get rid of whitespace, however it is not working.
Here is the part of the code related to this issue (there are a few other functions I did not include, unless they seem to the source of the issue):
#include <iostream>
#include <string>
#include <cctype>
#include <vector>
using namespace std;
void get_nums(vector<int>& num_vec);
int main ()
{
int num1;
int num2;
cout << "\n Please, enter your HW: ";
vector<int> num_vec;
cin>>ws;
cout.flush();
do
{
cin>>ws;
cin>>num1;
num_vec.push_back(num1);
if(cin.peek() == ',')
{
cin.ignore();
}
else if(cin.peek() == '-')
{
cin.ignore();
cin>>num2;
for(++num1; num1<=num2; num1++)
{
num_vec.push_back(num1);
}
if(cin.peek() == ',')
{
cin.ignore();
}
}
}
while (cin.peek() != '\n');
cout<< "\n Do Problems: ";
for(int z=0; z<num_vec.size(); z++)
{
if(z+1==num_vec.size())
{
cout<<num_vec[z];
}
else if(z+2==num_vec.size())
{
cout<<num_vec[z]<<",and ";
}
else
{
cout<<num_vec[z]<<", ";
}
}
return 0;
}
I would use std::getline() to read the user's entire input in one go, and then use std::istringstream to parse it, eg:
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
void get_nums(std::vector<int> &num_vec)
{
std::string line, tokens;
std::getline(std::cin, line);
std::istringstream input(line);
while (std::getline(input, tokens, ','))
{
std::istringstream values(tokens);
int num;
if (!(values >> num))
continue;
values >> std::ws;
char ch = values.peek();
if (ch == '-')
{
values.ignore();
int num2;
if (!(values >> num2))
continue;
while (num <= num2)
num_vec.push_back(num++);
}
else if (ch == std::char_traits<char>::eof())
num_vec.push_back(num);
}
}
int main()
{
std::vector<int> num_vec;
std::cout << "\n Please, enter your HW: " << std::flush;
get_nums(num_vec);
if (!num_vec.empty())
{
std::sort(num_vec.begin(), num_vec.end());
std::cout << "\n Do Problems: ";
std::cout << num_vec[0];
for(int z = 1; z < num_vec.size(); ++z)
{
std::cout << ", ";
if ((z+1) == num_vec.size())
std::cout << "and ";
std::cout << num_vec[z];
}
}
else
std::cout << "\n No Input! ";
return 0;
}
Input: 25,1,3-6
Output: 1,3,4,5,6,25
Input: 25,1,3 - 6
Output: 1,3,4,5,6,25
Input: 2 5, 1 , 3- 6
Output: 1,3,4,5,6 1
1: 2 5 is not valid input in this code. If you want it to be, you will have to add some extra code to handle space-delimited numbers in addition to comma-delimited numbers.

Do-While to ask user to repeat entire int main programme

Very new to programming and l can't find any basic explanation online or code that will work well for what l need. I have a fairly long piece of programme (approx 300 lines) it all works. This is the structure to give an idea:
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
//code....
{
//code... etc...
}
}
I want to ask the user to repeat the programme. If enters y, then repeat int main up to the point of asking the same repeat question again. Else to cout<< "e.g. Thank you, goodbye";
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <vector>
#include <algorithm>
//using namespace std; <--- Don't use using namespace std, it pollutes the namespace
void repeat()
{
//... code to repeat
}
int main()
{
//code....
char answer;
while((std::cin >> answer) != 'y')
{
repeat();
}
}
#include <iostream>
#include <conio.h>
using namespace std;
//Class
class DollarToRs {
public:
int Dollar;
int Rs;
int ToRs;
ConversionToRs() {
cout << "Enter the amount of Dollar: ";
cin >> Dollar;
ToRs = Dollar * 154;
cout << "This is the total amount in PKR: " << ToRs <<endl;
}
};
int main()
{
//Dollar Convertion Function
DollarToRs convert;
convert.ConversionToRs();
//For Repeating Program
int repeat;
int exit;
cout << "To repeat program enter 1" <<endl;
cin >> repeat;
while (repeat == 1) {
convert.ConversionToRs();
cout << "To repeat program enter 1" <<endl;
cin >> repeat;
}
exit =0;
if (exit == 0) {
}
getch();
return 0;
}
Here's an example of a simple solution:
int main()
{
for (;;) // "infinite" loop (while (true) is also possible)
{
// stuff to be repeated here
cout << "Repeat? [y/n]" << endl;
char answer;
cin >> answer;
if (answer == 'n')
break; // exit loop
} // else repeat
cout << "Thank you, goodbye" << endl;
}
Here's another one:
int main()
{
bool repeat = true;
while (repeat)
{
// stuff to be repeated here
cout << "Repeat? [y/n]" << endl;
char answer;
cin >> answer;
repeat = answer == 'y';
}
cout << "Thank you, goodbye" << endl;
}
As a side note, don't do this: #include <stdlib.h>. In C++ you should use the c prefixed header file names when using the C headers: #include <cstdlib> and #include <ctime>.