How to check for non-integer input in multiple inputs - c++

I was working on this program for a while and I can not find a way to make the cin.fail() output "Incorrect input." on 2nd,3rd,4th,... digit of the second binary number. For example "11111 a11" is detected as input fail but "11111 1a1" or "11111 1abfcds" is not detected. It seems to only check the 1st digit. Here is the program.
#include <iostream>
#include <cmath>
using namespace std;
int binary_decimal_1(int n);
int binary_decimal_2(int m);
int decimal_binary(int s);
int main()
{
int n, m, s;
cout << "Input 2 binary numbers" << endl;
cin >> n;
if (cin.fail())
{
cout << "Incorrect input." << endl;
return 0;
}
cin >> m;
if (cin.fail())
{
cout << "Incorrect input." << endl;
return 0;
}
s= binary_decimal_1(n) + binary_decimal_2(m);
cout << "Sum: " << decimal_binary(s) << endl;
return 0;
}
int decimal_binary(int s) /* Function to convert decimal sum to binary result.*/
{
int rem, i=1, binary=0;
while (s!=0)
{
rem=s%2;
s/=2;
binary+=rem*i;
i*=10;
}
return binary;
}
int binary_decimal_1(int n) /* Function to convert binary number 1 to decimal.*/
{
int decimal_1=0, i=0, rem;
while (n!=0)
{
rem = n%10;
n/=10;
decimal_1 += rem*pow(2,i);
++i;
}
return decimal_1;
}
int binary_decimal_2(int m) /* Function to convert binary number 2 to decimal.*/
{
int decimal_2=0, i=0, rem;
while (m!=0)
{
rem = m%10;
m/=10;
decimal_2 += rem*pow(2,i);
++i;
}
return decimal_2;
}

Input processing terminates on the first non-numeric character encountered.
Once you get a value to parse, use a function to validate it:
template <typename T>
bool convert_to( const std::string& s, T& value )
{
std::istringstream ss( s );
ss >> value >> std::ws;
return ss.eof();
}
--Typed off the top of my head; typos may have occurred.

I fixed my program by using strings and checking those for incorrect input, converting strings to integers and now it works.
#include <iostream>
#include <cmath>
#include <sstream>
using namespace std;
int binary_decimal_1(int n);
int binary_decimal_2(int m);
int decimal_binary(int s);
int main()
{
string n, m;
int s;
cout << "Input 2 binary numbers:" << endl;
cin >> n;
cin >> m;
bool bValidn = true; // Function to check for non numeric input in n.
for (unsigned int nIndex=0; nIndex < n.length(); nIndex++)
if (!isdigit(n[nIndex]))
{
bValidn = false;
cout << "Bad input.";
return 0;
}
bool bValidm = true; // Function to check for non numeric input in m.
for (unsigned int nIndex=0; nIndex < m.length(); nIndex++)
if (!isdigit(m[nIndex]))
{
bValidm = false;
cout << "Bad input.";
return 0;
}
// Now to convert strings into integers.
int intn;
stringstream convertn(n);
if ( !(convertn >> intn) )
intn = 0;
int intm;
stringstream convertm(m);
if ( !(convertm >> intm) )
intm = 0;
// And the hardest part.
s = binary_decimal_1(intn) + binary_decimal_2(intm);
cout << "Sum is: " << decimal_binary(s) << endl << endl;
return 0;
}
int decimal_binary(int s) // Function to convert decimal sum to binary result.
{
int rem, i=1, binary=0;
while (s!=0)
{
rem=s%2;
s/=2;
binary+=rem*i;
i*=10;
}
return binary;
}
int binary_decimal_1(int intn) // Function to convert binary number 1 to decimal.
{
int decimal_1=0, i=0, rem;
while (intn!=0)
{
rem = intn%10;
intn/=10;
decimal_1 += rem*pow(2,i);
++i;
}
return decimal_1;
}
int binary_decimal_2(int intm) // Function to convert binary number 2 to decimal.
{
int decimal_2=0, i=0, rem;
while (intm!=0)
{
rem = intm%10;
intm/=10;
decimal_2 += rem*pow(2,i);
++i;
}
return decimal_2;
}

Related

use of undeclared identifier 'data' C++

"Write a function, named sums(), that has two input parameters; an array of floats; and an integer,
n, which is the number of values stored in the array. Compute the sum of the positive values in the array
and the sum of the negative values. Also count the number of values in each category. Return these four
answers through output reference parameters.
Write a main program that reads no more than 10 real numbers and stores them in an array. Stop reading numbers when a 0 is entered. Call the sums() function and print the answers it returns. Also compute and print the average values of the positive and negative sets."
#include <iostream>
using namespace std;
void sums(float data[], int count, float& posSum, int& posCnt, float& negSum, int& negCnt);
double input(double UserInput);
int main()
{
float data[10];
int count = 10 ;
double UserInput = 0;
float posSum=0.0, negSum=0.0; //sum of positives and negatives
int posCnt =0, negCnt=0; // count of postive and negatives
input(UserInput);
sums(data, count, posSum,posCnt, negSum, negCnt);
cout << "Positive sum: " << posSum << endl;
cout << "Positive count:" << posCnt << endl;
cout << "Negative sum: " << negSum << endl;
cout << "Negative count:" << negCnt << endl;
return 0;
}
double input(double UserInput) {
for(int i = 0; i < 10; i++){
cout << "Enter a real number or '0' to stop: " ;
cin >> UserInput;
if(UserInput == 0)break;
data[i] = UserInput;
}
return UserInput;
}
void sums(float data[], int count, float& posSum, int& posCnt, float& negSum, int& negCnt){
int i;
for(i = 0; i < count; i++){
if(data[i] > 0){
posCnt += 1;
posSum += data[i];
}
else{
negCnt += 1;
negSum += data[i];
}
}
}
It gives me an error when trying to compile it saying "use of undeclared identifier 'data'" on line 32 in the input function.
It is because the data is not declared in the function input, you should use a float pointer.
void input(float *data)
{
float UserInput;
for (int i = 0; i < 10; i++)
{
cout << "Enter a real number or '0' to stop: ";
cin >> UserInput;
if (UserInput == 0)break;
data[i] = UserInput;
}
return;
}
int main()
{
float *data;
data = (float*)malloc(10 * sizeof(float));
input(data);
cout << data[0];
free(data);
system("pause");
return 0;
}
This should be an accurate example. Good Luck with your following homework.

c++ validate input value before add it to array

My target is to validate input value before add it into array. Current code used:
int main()
{
int temp;
int arr[5];
for(int i = 0; i < 5; i++)
{
// validate here
cin >> arr[i];
}
return 0;
}
and my validation method:
int validateInput(string prompt)
{
int val;
while (true)
{
cin.clear();
cin.sync();
cout << prompt;
cin >> val;
if (cin.good() && val >= -50 && val <= 50)
{
break;
}
else
cin.clear();
cout << "Invalid input! number must be between -50 and 50" << endl;
}
return val;
}
How is that possible?
Your validateInput should just deal with validation: it should answer "is x valid or not valid?"
bool validateInput(int x)
{
return val >= -50 && val <= 50;
}
When reading from stdin, use validateInput and branch accordingly:
for(int i = 0; i < 5; i++)
{
int temp;
cin >> temp;
if(cin.good() && validateInput(temp))
{
arr[i] = temp;
}
else
{
cout << "Invalid input! number must be between -50 and 50" << endl;
// handle invalid input
}
}
If you want to further abstract the idea of "only reading valid numbers from std::cin", you can use an higher-order function:
template <typename TFValid, typename TFInvalid, typename TFInvalidIO>
decltype(auto) processInput(TFValid&& f_valid, TFInvalid&& f_invalid, TFInvalidIO&& f_invalid_io)
{
int temp;
cin >> temp;
if(!cin.good())
{
// Invalid IO.
return std::forward<TFInvalidIO>(f_invalid_io)();
}
if(validateInput(temp))
{
// Valid IO and datum.
return std::forward<TFValid>(f_valid)(temp);
}
// Valid IO, but invalid datum.
return std::forward<TFInvalid>(f_invalid)(temp);
}
Usage:
for(int i = 0; i < 5; i++)
{
processInput([&](int x){ arr[i] = x; },
[](int x){ cout << x << " is invalid"; },
[]{ cout << "Error reading from cin"; });
}
If you want more genericity you can also pass validateInput and the type of input as an additional parameters.
Vittorio's answer above is spot on. For completeness, if you want exactly 5 elements:
#include <string>
#include <iostream>
using namespace std;
bool validateInput(int inValue)
{
return inValue >= -50 && inValue <= 50;
}
int main()
{
int _arr[5];
int _currentIdx = 0;
int _tmp;
while (_currentIdx < 5)
{
cin >> _tmp;
if (validateInput(_tmp))
{
_arr[_currentIdx] = _tmp;
_currentIdx++;
}
else
{
cout << "Invalid input! number must be between -50 and 50" << endl;
}
}
}
replace
cin >> temp;
with
arr[i] = validateInput("some str");

Getting (lldb) output and hang on runtime

I have a simple program that is calculating factorials, permutations and combinations. I feel good about my math but for whatever reason I cannot get this program to execute. Full disclosure I am new student to C++. Here is my code:
#include <iostream>
using namespace std;
int factorial(int);
int permutations(int, int);
int combinations (int ,int);
void perms_and_combs(int, int, int&, int&);
int numPerms;
int numCombs;
int main() {
int factorialVal;
cout << "enter an int!\n";
cin >> factorialVal;
cout << "The factorial of " << factorialVal << " is " << factorial(factorialVal) << endl;
int permVal1;
int permVal2;
do {
cout << "Input a two values: ";
cin >> permVal1;
cout << ", ";
cin >> permVal2;
} while ( permVal1 < 0 || permVal2 > permVal1);
cout << "test"; // This line doesn't get executed
perms_and_combs(permVal1, permVal2, numPerms, numCombs);
cout << "Number of permutations: "<<numPerms << ". Number of combinations: " << numCombs;
return 0;
}
int factorial(int n) {
int product = 1;
for (int i = 1; i <= n; i++) {
product *= i;
}
return product;
}
int permutations (int n, int k) {
int result;
int denominator = n-k;
cout << denominator;
result = (factorial(n)/factorial(denominator));
return result;
}
int combinations (int n, int k) {
int result;
result = permutations(n, k) * (1/factorial(k));
return result;
}
void perms_and_combs(int n, int k, int& numPerms, int& numCombs) {
numPerms = permutations(n, k);
numCombs = combinations(n, k);
return;
}

Using strtol to get long double in c++

I am trying to get the long double out of an array.
long double num;
char * pEnd;
char line[] = {5,0,2,5,2,2,5,4,5,.,5,6,6};
num = strtold(line1, &pEnd);
For some reason the num i am getting is rounded to 502522545.6
I am quite new to C++ so is there something i am doing wrong ? What needs to be done to get the entire number in the num instead of the rounded up?
Thank you for the help !!!
Sorry that's my first post here =)
So the entire program code is as following :
class Number
{
private:
long double num ;
char line[19], line2[19];
int i, k;
public:
Number()
{}
void getData()
{
i = 0;
char ch= 'a';
cout << "\nPlease provide me with the number: ";
while ((ch = _getche()) != '\r')
{
line[i] = ch;
line2[i] = ch;
i++;
}
}
void printData() const
{
cout << endl;
cout << "Printing like an Array: ";
for (int j = 0; j < i; j++)
{
cout << line[j];
}
cout << "\nModified Array is: ";
for (int j = 0; j < (i-k); j++)
{
cout << line2[j];
}
cout << "\nTHe long Double is: " << num;
}
void getLong()
{
char * pEnd;
k = 1;
for (int j = 0; j < i; j++)
{
if (line2[j+k] == ',')
{
k++;
line2[j] = line2[j + k];
}
line2[j] = line2[j + k];
}
line2[i -k] = line2[19];
num = strtold(line2, &pEnd);
}
};
int main()
{
Number num;
char ch = 'a';
while (ch != 'n')
{
num.getData();
num.getLong();
num.printData();
cout << "\nWould you like to enter another number ? (y/n)";
cin >> ch;
}
return 0;
}
The idea is that the number entered is in the following format ($50,555,355.67) or any other number. The program then removes all signs apart of numbers and "."
Then i tried to get the long double num out of an array.
If you run the program you always get the rounded number from num.
The C++ way of doing this is pretty simple:
#include <sstream>
#include <iostream>
#include <iomanip>
int main() {
const std::string line = "502522545.566";
long double num;
std::istringstream s(line);
s >> num;
std::cout << std::fixed << std::setprecision(1) << num << std::endl;
}
Using modern C++ you can simply do:
auto line = "502522545.566"s;
auto num = std::stold(line);
Live example
Theres probably a more C++ way, but sscanf will work:
const char *str = "3.1459";
long double f;
sscanf(str, "%Lf", &f);

Segmentaton Fault

I was trying to work on a CodeChef problem (Problem Link :: http://www.codechef.com/problems/K2). The code should take in a input for each test case, process, display the result, before moving to the next testcase. But it is just taking inputs without any output.
I am unable to figure out the error as the g++ compiler isn't giving any.
#include <iostream>
#include <string>
#include <cstring>
#include <stdio.h>
using namespace std;
using std::string;
char baseArr[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
bool isPalin(string number)
{
int len=number.size();
bool flag=true;
for(int i=0; i<len/2, flag==true; i++)
{
if(number[i]==number[len-(i+1)])
continue;
else
{
flag=false;
}
}
return flag;
}
string baseChange(long int number, int base)
{
int i=1;
int rem=0;
string output =" ";
while(number>0)
{
rem=number%base;
number=number/base;
output=baseArr[rem]+output;
}
return output;
}
int main()
{
long int input;
int testcase;
string number;
int i;
bool palin=false;
scanf("%d", &testcase);
while(testcase--)
{
palin=false;
scanf("%ld", &input);
for(i=2; palin==false;i++)
{
{
palin=isPalin(baseChange(input, i));
}
}
printf("%d\n",i);
}
}
You assume that the maximum base will be 16, but this may not be the case. You are probably getting a segmentation fault for accessing baseArr beyond valid index. I have not thought of the solution, but I believe the actualy solution can be implemented without considering any character value for the digits.
A solution to the Palindrome problem:
#include <sstream>
#include <cstdlib>
bool test_palindrome(const std::string& value)
{
for (unsigned int i = 0; i < value.length() / 2; i++)
{
if (value[i] != value[value.length() - 1 - i])
return false;
}
return true;
}
std::string find_palindrome(unsigned long num)
{
std::string ret = "";
for (int i = 2; i <= 32; i++)
{
char buffer[100] = {0};
std::string value = ::itoa(num, buffer, i);
std::cout << "Testing: Base=" << i << " Value=" << value << std::endl;
bool test = test_palindrome(value);
if (test)
{
std::stringstream ss;
ss << value << " (base " << i << ")";
ret = ss.str();
break;
}
}
return ret;
}
int main()
{
unsigned long input = 0;
std::cout << "Enter number to search: ";
std::cin >> input;
std::string palin = find_palindrome(input);
std::cout << std::endl << "Palindrome Found: " << palin << std::endl;
return 0;
}