I'm doing a problem where it asks to input an account number, which consists only of four digits. This has to be accomplished with basic beginner C++.
I need to figure out a way to restrict the input of the integer to four digits. A user should be able to put in 0043 or 9023 or 0001 and it should be an acceptable value....
I think I know how to accomplish it with a string.... getline(cin,input) and then check if input.length()==4?
But I've no idea how I would even do this with an integer input.
Note that if 0043 is intended to be distinct from 43, then the input is not in fact a number, but a digit string, just like a telephone "number".
Read the line as a string input.
Check that the length of input is 4.
Check that each character in the string is <= '9' and >= '0'.
Something like:
std::string read4DigitStringFromConsole()
{
bool ok = false;
std::string result;
while (!ok)
{
std::cin >> result;
if (result.length() == 4)
{
bool allDigits = true;
for(unsigned index = 0; index < 4; ++index)
{
allDigits = allDigits && (
(result[index] >= '0') &&
(result[index] <='9')
);
}
ok = allDigits;
}
}
return result;
}
Something like this should work. Once the user enters something with exactly four characters you can validate it. The rest of the logic is up to you.
#include <iostream>
#include <string>
int main() {
std::cout << "Enter a PIN Number: ";
std::string pinStr;
while(std::getline(std::cin,pinStr) && pinStr.size() != 4) {
std::cout << "Please enter a valid value\n";
}
}
Should you want to store it in an integer form, holding the integers in an std::vector might be beneficial. You can do this easily (loop unrolling was for clarity):
#include <iostream>
#include <string>
#include <vector>
int main() {
std::cout << "Enter a PIN Number: ";
std::string pinStr;
while(std::getline(std::cin,pinStr) && pinStr.size() != 4 ) {
std::cout << "Please enter a valid value\n";
}
std::vector<int> pin;
pin[0] = pinStr[0] - '0';
pin[1] = pinStr[1] - '0';
pin[2] = pinStr[2] - '0';
pin[3] = pinStr[3] - '0';
//pin now holds the integer value.
for(auto& i : pin)
std::cout << i << ' ';
}
You can see it running here
I like your idea to use a string as the input. This makes sense because an account "number" is simply an identifier. You don't use it in calculations. By if (sizeof(input)==4) I think you are trying to check the length of the string. The correct way to do this is if (input.length() == 4). This will check that the user inputs 4 characters. Now you need to make sure that each of the characters is also a digit. You can do this easily by taking advantage of the fact that the ASCII codes for digit characters are ordered as you expect. So if (input[i] >= '0' && input[i] <= '9') will do the trick with an appropriate for loop for the index i. Also, you probably need some kind of loop which continues to ask for input until the user enters something which is deemed to be correct.
Edit:
As an alternative to checking that each character is a digit, you can attempt to convert the string to an int with int value = atoi(input.c_str());. Then you can easily check if the int is a four-or-less-digit number.
// generic solution
int numDigits(int number)
{
int digits = 0;
if (number < 0) digits = 1; // remove this line if '-' counts as a digit
while (number) {
number /= 10;
digits++;
}
return digits;
}
similar to this post.
Then you can call this function to check if the input is 4 digits.
You probably want your code to be responsive to the user input, so I would suggest getting each character at a time instead of reading a string:
std::string fourDigits;
char currentDigit;
std::cout << "Enter 4 digits\n";
for(int i = 0; i < 4; ++i)
{
currentDigit = getch();
if(isdigit(currentDigit))
{
fourDigits += currentDigit;
std::cout << currentDigit; // getch won't display the input, if it was a PIN you could simply std::cout << "*";
}
else
{
// Here we reset the whole thing and let the user know he entered an invalid value
i = 0;
fourDigits = "";
std::cout << "Please enter only numeric values, enter 4 digits\n";
}
}
std::cout << "\nThe four digits: " << fourDigits.c_str();
This way you can handle gracefully invalid character instantly. When using strings, the input will only be validated once the user hits Enter.
So I was going over how I can use an integer type to get the input, and looked at char... since it's technically the smallest integer type, it can be used to get the code... I was able to come up with this, but it's definitely not refined yet (and I'm not sure if it can be):
int main() {
int count=0;
while(!(count==4)){
char digit;
cin.get(digit);
count++;
}
return 0;
}
So, the loop keeps going until 4 characters are collected. Well, in theory it should. But it doesn't work. It'll stop at 2 digits, 5 digits, etc.... I think it could be the nature of cin.get() grabbing white space, not sure.
Related
I want to ask 6 digit pins from user, I tried this code, it does work. The problem is that it cannot read pin starting from 0. The objective of the code is to read 6 digit pin no matter what the start is, as long as it is an integer it will read the correct output.
using namespace std;
int main(){
int pin[0];
cin>>pin[0];
if (pin[0] >= 100000 && pin[0] <= 999999) {
cout << pin[0];
}
else {
cout << "Invalid input!";
}
}```
On the one hand you want to read an integer (you are comparing it to 100000 and 999999) on the other hand you want to read individual digits into an array. It cannot be both. And you cannot have an array of size 0.
Just stay with the single integer. If you want to access individual digits you can convert it to a string and access characters (you already made sure that it has 6 digits):
#include <iostream>
#include <string>
int main(){
int pin;
std::cin>>pin;
if (pin >= 100000 && pin <= 999999) {
std::cout << pin << "\n";
std::string pin_string = std::to_string(pin);
for (size_t i=0; i<6; ++i){
std::cout << pin_string[i] << "\n";
}
}
else {
std::cout << "Invalid input!";
}
}
Heres one way to do it.
Read CIN as std::string
Regex recv string for digit only
Confirm recv string len is == 6
Do w/e you want with it from there
Another way could be getChar()
I have looked in several places on the Internet but cannot find what I am looking for. Basically I am trying to understand data validation and filter out all user input except either the number 1 or 2. I have found information for validating ints. Found stuff on filtering out chars and strings. But when I try to put them together it doesn't work. Basically if the user enters something that is not 1 or 2, it does not end a loop asking for correct input.
I have included more details in the comments in the code below.
Any help is appreciated!
#include <iostream>
#include <string>
int main()
{
std::cout << "Please enter 1 or 2. No other numbers or characters."
<< std::endl;
std::string numberString;
//Used a string so if the user enters a char it gets converted to an
//integer value of 0.
getline(std::cin, numberString);
int numberInteger = atoi(numberString.c_str());
//If the user enters the wrong number, char, or string,
//the program goes to this area of code.
//But if a subsequent correct entry is made, the loop does not end.
if (numberInteger < 1 || numberInteger > 2)
{
do
{
//Tried using these two lines of code to clear the input buffer,
//but it doesn't seem to work either:
//std::cin.clear();
//std::cin.ignore(std::numeric_limits <std::streamsize>::max(), '\n');
std::cout << "Invalid input. Please enter 1 or 2. No other numbers or characters."
<< std::endl;
getline(std::cin, numberString);
int numberInteger = atoi(numberString.c_str());
} while (numberInteger < 1 || numberInteger > 2);
}
else
{
std::cout << "You entered either 1 or 2. Great job! "
<< std::endl;
}
return 0;
}
#include <cctype>
#include <limits>
#include <iostream>
std::istream& eat_whitespace(std::istream& is)
{
int ch;
while ((ch = is.peek()) != EOF && ch != '\n' &&
std::isspace(static_cast<char unsigned>(ch))) // 0)
is.get(); // As long as the next character
// is a space, get and discard it.
return is;
}
int main()
{
int choice;
while (std::cout << "Please enter 1 or 2. No other numbers or characters: ",
!(std::cin >> std::skipws >> choice >> eat_whitespace) || // 1)
std::cin.peek() != '\n' || // 2)
choice < 1 || 2 < choice) { // 3)
std::cerr << "I said 1 or 2 ... nothing else ... grrr!\n\n";
std::cin.clear(); // 4)
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 5)
}
std::cout << "Input was " << choice << '\n';
}
0) Don't feed isspace() negative values.
1) Extraction of an int failed. Allow whitespace before and after the int.
2) If the next character in the stream is not a newline character, there is garbage left eat_whitespace() didn't swallow --> complain.
3) choice not in range.
4) clear flags to make sure input functions will work again.
5) ignore up to maximum streamsize characters untill the next newline.
My goal is to make a program that inputs a phone number and outputs it in a standard format. It skips over any non-number characters, will output if there are not enough digits, and will also skip over any digits after the first ten digits. My raptor worked without a hitch, but it's been difficult to translate it to C++.
I am using Microsoft Visual Studio.
The problem is it is not running. If I put in anything more then one number in, I receive a fail error.
I am having some difficulty running this code.
Any and all help and advice would be greatly appreciated.
#include <iostream>
#include <string>
using namespace std;
void format(char outArray[], string inNumber)
{
outArray[0] = '(';
outArray[4] = ')';
outArray[5] = ' ';
outArray[9] = '-';
outArray[1] = inNumber[0];
outArray[2] = inNumber[1];
outArray[3] = inNumber[2];
outArray[6] = inNumber[3];
outArray[7] = inNumber[4];
outArray[8] = inNumber[5];
outArray[10] = inNumber[6];
outArray[11] = inNumber[7];
outArray[12] = inNumber[8];
outArray[13] = inNumber[9];
}
int main()
{
string phone, inNumber;
cout << "Please enter a phone number: ";
cin >> phone;
int index = 0;
int num = 0;
char outArray[14];
for (index; phone[index] >= '0' && phone[index] <= '9'; index++)
{
inNumber[num] = phone[index];
num++;
}
if (inNumber.size() > 10)
{
format(outArray, inNumber);
cout << "The properly formatted number is: ";
cout << outArray;
}
else {
cout << "Input must contain at least 10 digits." << endl;
}
system("pause");
return 0;
}
A few things to note:
Use std::string instead array of char array.
You do not need to check charters using a for loop unless you are not sure about the input(phone). However, if that's the case, use std::getline() to get the input and parse as follows using a range-based for loop.
You can use std::isdigit to check the character is a digit.
My goal is to make a program that inputs a phone number and outputs it
in a standard format. It skips over any non-number characters, will
output if there are not enough digits, and will also skip over any
digits after the first ten digits.
That means the number should have a minimum length of 10. Then the
if statement should be if (inNumber.size() >= 10)
Need a pass by ref call in the function format(), since you want to change the content of outArray. Additionally, inNumber could be a
const ref, since we do not change this string.
Updated code: (See a sample code online)
#include <iostream>
#include <string>
#include <cstddef> // std::isdigit, std::size_t
void format(std::string& outArray, const std::string& inNumber) /* noexcept */
{
for (std::size_t index = 0; index < 10; ++index)
{
if (index == 0) outArray += '(';
else if (index == 3) outArray += ") ";
else if (index == 6) outArray += '-';
outArray += inNumber[index];
}
}
int main()
{
std::string phone;
std::cout << "Please enter a phone number: ";
std::getline(std::cin, phone);
std::string inNumber;
for (char letter : phone)
if (std::isdigit(static_cast<unsigned char>(letter))) // check the letter == digits
inNumber += letter;
if (inNumber.size() >= 10)
{
std::string outArray;
format(outArray, inNumber);
std::cout << "The properly formatted number is: ";
std::cout << outArray;
}
else {
std::cout << "Input must contain at least 10 digits." << std::endl;
}
return 0;
}
inNumber[num] = phone[index]; //undefined behavior.
You cannot subscript inNumber now, since its capacity is 0, thus it can not store or access any element here.
You may need to use string's constructor whose parameter has a size_t type or string::reserve or string::resize.
And I'm happy to see cppreference get more complete now, learn to use it: http://en.cppreference.com/w/cpp/string/basic_string
BTW, this function won't do anything you want to:
void format(char outArray[], string inNumber)
maybe you'd like to have an signature like this?
void format(char outArray[], string& inNumber)
this is my first question, so I hope I will not break any of the given rules here on forum. I would like to ask you for help. Im really programming noob, but for homework I have to make a programm in C++ which will add 2 binary numbers. I was able to make it throught converting to a decimal and adding them. I did it bcs I already had some parts for it in my PC. My question is, everything is working fine unless I enter really big binary numbers. Changing data types make difference in results when our school program checks the code. Im not sure waht to change exactly. Thank you in advance. It looks like proble occure when decimal number with "e" has to be converted-
#include <iostream>
#include <cmath>
#include <string>
#include <vector>
using namespace std;
int main ()
{
int k = 0;
int l = 0;
int i = 0;
int j = 0;
double number = 0;
double numberb = 0;
long dec;
string input;
string inputb;
cout << "Enter two binary numbers:" << endl;
cin >> input >> inputb;
if(cin.fail ())
{cout << "Wrong input." << endl;
return 0;
}
for (i = input.length() - 1; i>=0; i-- )
{
if (input[i] != '1' && input[i] != '0')
{
cout << "Wrong input." << endl;
return 0;
}
if (input[i] == '1')
{
number += pow((double)2,(int)j);
}
j++;
}
for (k = inputb.length() - 1; k>=0; k-- )
{
if (inputb[k] != '1' && inputb[k] != '0')
{
cout << "Wrong input." << endl;
return 0;
}
if (inputb[k] == '1')
{
numberb += pow((double)2,(int)l);
}
l++;
}
dec = number+numberb;
vector <double> bin_vector;
long bin_num;
while ( dec >= 1 )
{
bin_num = dec % 2;
dec /= 2;
bin_vector.push_back(bin_num);
}
cout << "Soucet: ";
for ( int i = (double) bin_vector.size() - 1; i >= 0; i-- )
cout << bin_vector[i] << "";
cout << endl;
return 0;
}
Probably your teacher told you that double numbers are great for large numbers. They are, but they have a big disadvantage: They cannot represent large numbers exactly, since they (roughly speaking) only store the first few digits of the number, together with the position of the decimal point, like your pocket calculator shows (for example, 123456E13).
So you should not use double numbers here at all, since you need precise results, no matter how large your numbers are. A better idea is process both strings simultaneously and store the result digit by digit in another string, called result.
By the way: Since double numbers can usually store 53 binary digits precisely, it's good that your tested the program with even more digits.
I'm working on homework and I'm stumped on this problem: Write a program that prompts the user to input an integer and then outputs both the individual digits of the number and the sum of the digits. For example, it should output the individual digits of 3456 as 3 4 5 6, [...], output 4000 as
4 0 0 0, and the individual digits of -2345 as 2 3 4 5.
Here's my code so far:
int main()
{
string a; //declares string
cout << "Type an integer: "; //prompts user to input an integer
cin >> a; //stores into string a
cout << "There are " << a.size() << " digits in " << a << endl; //retrieves length of string a
cout << a.at(0);
cout << endl;
system ("pause"); //pauses the system so user can read the screen
return 0; //returns 0 if program works properly
}
Can anyone enlighten me on what I'm doing wrong/what my next step is?
So the steps are..
store the input
display them all one by one separated by spaces
figure out the sum and display that
.
#include<string>
#include<iostream>
using namespace std;
int main()
{
string a;
cout << "Type an integer: ";
// 1. store the input
cin >> a;
// 2. display them all one by one separated by spaces
for(int i=0;i<a.size();++i)
cout << a[i] << ' ';
cout << endl;
// 3. figure out the sum and display that
int total = 0;
for(int i=0;i<a.size();++i)
total += a[i] - '0';
cout << total << endl;
system("pause");
return 0;
}
The tricky part is getting the correct sum in step 3.
total += a[i] - '0';
Lets say for example that a[i] is the character '4'. The ASCII value of character '4' is the integer equivalent of 52, and the ASCII integer equivalent of '0' is 48. Therefore if we take '4' - '0', we will get the difference of 4, which is the integer representation we are looking for in this case.
Here is a simple ASCII chart with character values.
Hope this helps!
You probably want to input the number as a string. This will allow you to do digit by digit processing. Then the user will enter the number once instead of many times as digits.
You could try this piece of code:
int num = 0;
cin>>num;
//Make sure array is large enough to hold all digits
//For an int 10 digits it the max
int digits[10] = {0};
//This variable tracks the count of actual number of
//digits extracted from user input
int digitCount = 0;
while (num > 0)
{
digits[digitCount] = num % 10; //Extract digit at units place
num = num / 10; //Advance through the number
digitCount++;
}
for(int count= digitCount-1 ; count >= 0; count-- )
{
cout<<digits[count]<<" ";
}
Note that the printing loop runs backwards (i.e from digitCount to zero) because the digits are extracted and stored starting from the units place. For a number a like 12345 the digits array will contain 5 4 3 2 1.
Rhonda, I can understand your frustration, computers are like that... they do what you say, not what you mean :-) Hang in there.
You say your program should output each of the digits in the number, yet your program asks the user to enter each of the digits. That is confusing.
Also, you first assign a value to "num" here
cin >> num;
then you overwrite "num" in this line
cin >> num >> a;
I'm not sure what you mean to do here, but what you're telling the computer to do is to read an integer from the input and assign it to "num" and assign the rest to the line to string "a"... if the rest of the line just has a space, the space will be discarded... it acts as a separator. That is probably confusing you as well.
int main()
{
int runningTotal = 0;
std::string inputString;
std::cin >> inputString;
for ( std::string::iterator _it = inputString.begin();
_it != inputString.end(); ++_it )
{
// *_it now represents an individual char of the input string
char a = *_it; char* b = &a;
if ( a != '-' )
{
runningTotal += atoi( std::string( b ).c_str() );
std::cout << *_it << " ";
}
}
std::cout << std::endl << "Total of all digits: " << runningTotal << std::endl;
std::cin.get();
std::system( "pause" );
return 0;
}
I threw this together quickly for you. Hope it's of help.