User input validation test in C++ - c++

i'm having trouble with exercise 9 from chapter 5 of "Bjarne Stroustrup Programming Principles and Practice Using C++".
The chapter is about errors, and the exercise says " Modify the program from excercise 8 to write out an error if the result cannot be represented as an int".
I have tried using various variations of
if (!cin)
error("Input is not an integer");
However the issue I get is that if I read in something that is not an integer it will then either display all the errors or just the "you wanted to sum more values than you entered" error.
This is my full code from excercise 8 before i tried to add the user input error:
#include <iostream>
#include "../../std_lib_facilities.h"
int main()
{
try {
int size = 0;
int numbers = 0;
int sum = 0;
vector<int>values;
cout << "Please enter how many numbers you want to sum\n";
cin >> size;
if (size < 1)
error("you have to enter at least one value!");
cout << "enter some integers and then | to sum them\n";
while (cin >> numbers)
values.push_back(numbers);
if (values.size() < size)
error(" You wanted to sum more values than you entered. ");
cout << "the sum of the first " << size << " numbers ( ";
for (int i = 0; i < size; ++i) {
sum += values[i];
cout << values[i] << " ";
}
cout << ") is : " << sum << "\n";
return 0;
}
catch (exception& e) {
cerr << "Error: " << e.what() << "\n";
keep_window_open();
return 1;
}
catch (...) {
cerr << "Oops: Unknown exception!\n";
keep_window_open();
return 2;
}
}

I think that you can use cin.fail() method to detect a wrong input.
for example
int numbers = 0;
cin >> numbers;
if (cin.fail())
{
/* run when the input is not integer. */
}

Related

Trying to validate user input for repeating values in 2D array

So I'm working on a Lo Shu Magic Square for my first programming class and I'm stuck. I'm sure everyone here will know what that is but just in case, it's a 2D array that takes 9 numbers from user input, but they have to be between that range (1-9) and also non repeating (where I'm stuck).
I can validate for numbers within the 1-9 range, but I'm having trouble also validating for the second condition of non-repeating numbers
Here's my code for the function that takes user input:
(Oh yea, the 2D array is 3x3 so ROWS = 3 and COLS = 3 and they're being passed to this function)
// Get numbers
void getNumbers(int magicSquare[][COLS], int ROWS)
{
cout << "\nEnter Nine Numbers (1-9)" << endl;
int num;
int n = 0;
for (int r = 0; r < ROWS; r++)
{
for (int c = 0; c < COLS; c++)
{
cout << "\tNumber " << (n + 1) << ": ";
cin >> num;
magicSquare[r][c] = num;
n++;
// Input validation
// Validate against numbers outside the range
while (num < 1 || num > 9)
{
cout << "\tError ... Invalid number. Try again" << endl
<< endl;
cout << "\tNumber " << (n) << ": ";
cin >> num;
magicSquare[r][c] = num;
}
// Validate against repeating numbers
while (...) //OMEGA STUCK
{
cout << "\tError ... " << num << " is already in the
Lo Shu Square. Try again" << endl <<endl;
cout << "\tNumber " << (n) << ": ";
cin >> num;
magicSquare[r][c] = num;
}
}
}
cout << endl;
}
I have tried several approaches, from using while loops, to trying temp arrays, and I'm currently attempting to create a new bool function and pass the array and input to it but with little success.
// Validate against repeating numbers
while (repeatNumbers(magicSquare, num)) // Calling boolean function (defined below)
{
cout << "\tError ... " << num << " is already in the Lo Shu Square.
Try again" << endl << endl;
cout << "\tNumber " << (n) << ": ";
cin >> num;
magicSquare[r][c] = num;
}
...
// Validate against repeating numbers function
bool repeatNumbers(int magicSquare[][COLS], int num)
{
bool status;
if (num == magicSquare[COLS][COLS]) //Here I get an error:
{ //"Reading invalid data from
status = true; //'magicSquare[COLS]'.
}
else
{
status = false;
}
return status;
}
Is there a way to ensure that reading a partially filled-in array is well-behaved, what's the best approach? I can't arrive at the correct way, and I just KNOW I'm missing something that is quite logical which my tired brain can't think of at this point.
Any ideas on how to test for both conditions?

How can I set my variable in C++ to 0 and prevent it from getting random?

I am a beginner in programming. I was doing some simple applications. I was already done with my programme when I realised that my variable is getting random, even if I set it to 0. I was trying to figure it out why. My goal is to add 1 to the "cor" variable when the answer is matching the random generated number, the "else" section is working as it has to be. Maybe someone more experienced can help me.
`
#include <iostream>
#include <string>
#include <time.h>
#include <Windows.h>
using namespace std;
int number;
int ynumber[5];
int cor = 0;
int falsed = 0;
int main()
{
cout << "Welcome to our lottery!" << endl;
cout << "We start in ..." << endl;
Sleep(2000);
for (int i = 3; i >= 0; i--)
{
system("cls");
cout << i << endl;
Sleep(1000);
}
system("cls");
srand(time(NULL));
for (int i = 0; i < 6; i++)
{
cout << "Type your " << i+1 << " number below" << endl;
cin >> ynumber[i];
number = rand() % 50 + 1;
cout << "The picked number is: " << number << endl;
Sleep(1000);
if (ynumber[i] == number)
{
cout << "Same same!" << endl;
cor = cor + 1;
}
else
{
cout << "Hope for better luck next time ;)" << endl;
falsed = falsed + 1;
}
}
system("cls");
cout << "Thank you for participating!" << endl << "Correct picked numbers: " << cor << endl << "Wrong picked numbers: " << falsed << endl << endl;
system("pause");
return 0;
}
`
int ynumber[5];
The length of your array is 5
for (int i = 0; i < 6; i++)
{
//...
cin >> ynumber[i];
You loop over the indices 0,1,2,3,4,5. Use your fingers to count the number of indices that you use. You'll notice that you access the array at 6 different fingers. 6 is more than 5. As such, we can conclude that you're accessing the array out of bounds. The consequence is that behaviour of your program is undefined.
Solution: Do not access an array out of bounds. The last index of array of length n is n - 1.
More generally: Don't rely on magic numbers. In this case, you could use instead:
for (int i = 0; i < std::size(ynumber); i++)

What can I do in this code to prompt an error when a negative number is used?

i was wondering what can I do to prompt an error when I input a negative number. I used a for loop for this program. What this program does, or at least its supposed to do, is to output the factor of any given number (if positive). But I am not sure how to make my code to prompt an error or at least keep asking for a number if the number that input is less or equal to 0.
I used the variable n as the number to input by the user.
I am really new to programming and I am eager to finish this program as soon as possible. Can you please assist?
#include <iostream>
#include <math.h>
#include <stdlib.h>
using namespace std;
int main()
{
double n;
cout << "Welcome to this program... Hope you like it" << flush << endl;
do
{
int i, fact = 1, n;
cout << "Please enter a value for the variable " "n: ";
cin >> n;
for (i = 1; i <= n; i++) {
fact = fact * i;
}
cout << "Factorial of " << n << " is: " << fact << endl;
cout << " Thanks for using this program... hope you liked it!" << endl;
} while (n >= 0);
return 0;
}
Commens in the code:
#include <iostream>
// it's best not to do using namespace std. It's a huge namespace
int main()
{
std::cout << "Welcome to this program... Hope you like it\n";
do
{
int i, fact = 1, n;
std::cout << "Please enter a value for the variable " "n: ";
std::cin >> n;
// if std::cin is in a failed state then break out of the loop.
if (std::cin.fail()) break;
// added check if n<0. if n<0 ptint error on stderr
if (n<0) {
std::clog << "Error: you must supply a number equal to or greater than zero\n";
} else { // if n>=0
for (i = 1; i <= n; i++) {
fact = fact * i;
}
std::cout << "Factorial of " << n << " is: " << fact << "\n";
}
} while (true); // <- now always true
std::cout << "\nThanks for using this program... hope you liked it!\n";
return 0;
}

Converting String to vector of Integers

FizzBuzz program. The user enters numbers separated by a comma. The program reads input and lets the computer know if divisible by 3, 5 or both. When the user enters 15,5,30, the program will only output the first number, 15 and stops there. What am I doing wrong?
void processVector(vector<int> intVector)
{
bool loop;
for (int i = 0; i < intVector.size(); i++)
{
loop = true;
}
}
int main()
{
cout << "Welcome to the FizzBuzz program!" << endl;
cout << "This program will check if the number you enter is divisable by
3, 5, or both." << endl;
cout << "Please enter an array of numbers separated by a comma like so,
5,10,15" << endl;
cin >> userArray;
vector<int> loadVector(string inputString);
istringstream iss(userArray);
vector <int> v;
int i;
while (iss >> i);
{
v.push_back(i);
if (iss.peek() == ',')
iss.ignore();
if (i % 15 == 0)
{
cout << "Number " << i << " - FizzBuzz!" << endl;
}
else if (i % 3 == 0)
{
cout << "Number " << i << " Fizz!" << endl;
}
else if (i % 5 == 0)
{
cout << "Number " << i << " Buzz!" << endl;
}
else
{
cout << "Number entered is not divisable by 3 or 5." << endl;
}
}
system("pause");
}
Here is how I would approach the problem:
#include <iostream>
#include <string>
#include <vector>
int main() {
std::cout << "!!!Hello World!!!" << std::endl; // prints !!!Hello World!!!
std::cout << "Please enter your numbers seperated by a comma (5, 3, 5, 98, 278, 42): ";
std::string userString;
std::getline(std::cin, userString);
std::vector<int> numberV;
size_t j = 0; // beginning of number
for(size_t i = 0; i < userString.size(); i++){
if((userString[i] == ',') || (i == userString.size() -1)){ // could also use strncmp
numberV.push_back(std::stoi(userString.substr(j, i))); // stoi stands for string to int, and .substr(start, end) creates a new string at the start location and ending at the end location
j = i + 1;
}
}
for(size_t n = 0; n < numberV.size(); n++){
std::cout << numberV[n] << std::endl;
}
return(0);
}
This should give you a method to solve the problem (without handling the fizzbuzz part of your program) that I personally find simpler.
The basic form for using functions is:
<return type> <function_name(<inputs)>{
stuff
};
So, a basic function that takes a string and returns a vector (what you are wanting) would be:
std::vector myStringToVector(std::string inputString){
std::vector V;
// your code (see the prior example for one method of doing this)
return(V);
};
It also looks like they want a separate function for outputting your vector values, this could look something like:
void myVectorPrint(std::vector inputVector){
// your code (see prior example for a method of printing out a vector)
};
Thank you #Aaron for the help. Here is the finished code and it works great!
I had to take a little more time researching a few things and trying to understand which order and what to put where in terms of the functions and how to call them. I appreciate all the help as I said I am a noob.
#include "stdafx.h"
#include <iostream>
#include<sstream>
#include<string>
#include<vector>
using namespace std;
vector<int> loadVector(string inputString)
{
stringstream ss(inputString);
vector <int> numberV;
int n;
size_t j = 0; // beginning of number
for (size_t n = 0; n < inputString.size(); n++)
{
if ((inputString[n] == ',') || (n == inputString.size() - 1))
{
numberV.push_back(std::stoi(inputString.substr(j, n)));
j = n + 1;
}
}
return numberV;
}
void processVector(vector<int> intVector)
{
for (int i = 0; i < intVector.size(); i++)
{
int n = intVector.at(i);
if (n % 15 == 0)
{
cout << "Number " << n << " - FizzBuzz!" << endl;
}
else if (n % 3 == 0)
{
cout << "Number " << n << " Fizz!" << endl;
}
else if (n % 5 == 0)
{
cout << "Number " << n << " Buzz!" << endl;
}
else
{
cout << "Number entered is not divisable by 3 or 5." << endl;
}
}
}
int main()
{
cout << "Welcome to the FizzBuzz program." << endl
<< "Please enter an array of numbers separated by comma's (5, 10, 15)"
<< endl;
string inputString;
getline(cin, inputString);
try
{
vector<int> intVector = loadVector(inputString);
processVector(intVector);
}
catch (const exception& e)
{
cout << "Exception caught: '" << e.what() << "'!;" << endl;
}
system("pause");
return 0;
}

Trying to ask a user to provide a set of numbers, then have program determine if the numbers are in ascending order or not?

I am trying to create a program that asks the user for a set of numbers, first asking for the quantity of numbers, then having them input all the numbers. The program then checks the numbers, and determines whether or not the numbers given are in ascending order or not. Then, simply print out "yes ascending" or "no not ascending" and print out the array on one line..So far, my code will just always say that "yes, this is an increasing array!" Please look below for my code. Thanks in advance!..
tested: 1 2 3 4 5 6 --> pass
1 3 5 2 4 6 --> fail (still says it is an ascending array)
#include <iostream>
#include <string>
using namespace std;
bool isAscending(int arr[], int size)
{
for (int i=0; i < size-1; i++)
{
if (arr[i] > arr[i+1])
{
return false;
}
}
return true;
}
int main()
{
int arraysize = 0;
string numbers;
cout << "Enter the size of the array: " << endl;
cin >> arraysize;
if (arraysize < 1)
{
cout << "ERROR: you entered an incorrect value for the array size!" << endl;
}
cout << "Enter the numbers in the array, separated by a space, and press enter: " << endl;
numbers += ' ' + numbers;
cin >> numbers;
int arr[arraysize];
if ( isAscending(arr, arraysize))
{
cout << "This IS an increasing array!" << endl;
}
else
{
cout << "This is NOT an ascending array!" << endl;
}
for (i = 0; i < arraysize - 1; i++)
{
cout << arr[i];
}
return 0;
}
You're reading in "numbers", which you created as type String.
cout << "Enter the numbers in the array, separated by a space, and press enter: " << endl;
numbers += ' ' + numbers;
cin >> numbers;
Your numbers+= line isn't doing anything except adding a space to your numbers string before your cin happens... I know what you're trying to accomplish, and that won't do it.
Then you're suddenly making an array which, without initializing is filled with garbage, and immediately running isAscending on it:
int arr[arraysize];
if ( isAscending(arr, arraysize)){....}
I advise you declare your array before receiving input, read the input line and process it into INTEGERS, and then add each integer to your array. Here is a (crude) correction of the first section of code in your main that just reads in whitespace separated integers and fills the array with them:
int main(){
int arraysize = 0;
int number = 0;
cout << "Enter the size of the array: " << endl;
cin >> arraysize;
if (arraysize < 1) // you should really have this loop until you get correct input
{ cout << "ERROR: you entered an incorrect value for the array size!" << endl; }
int* arr = new int[arraysize];
cout << "Enter the numbers in the array, separated by a space, and press enter: " << endl;
int i = 0;
while(i < arraysize){
cin >> number;
arr[i] = number;
i++;
};
if ( isAscending(arr, arraysize)){ cout << "This IS an increasing array!" << endl; }
else{ cout << "This is NOT an ascending array!" << endl;}
for (int i = 0; i < arraysize; i++){
cout << arr[i];
if( (i+1) == arraysize){ cout << ". ";}
else cout << ", ";
}
return 0;
}
If you're going to whine about somebody giving partial answers that only address the asker's question, maybe you should take the time to write something yourself.