C++ Phone Number Program - c++

I am new to this forum and am looking for some assistance, any help would be greatly appreciated! I am stuck on this assignment for my programming fundamentals 1 class and am desperate at this point as I have been stuck for hours on end. Thank you.
Here is the prompt:
Many websites ask for phone numbers. The problem is that there are so many
different ways to represent a phone number. Examples include 817-555-1234,
817 555 1234 (c), and (817) 555-1234 x23. Write a C++ program which inputs
a string containing a phone number in any format and outputs it in the standard
format. For this assignment, the standard format is (817)555-1234.
Your c++ program should:
1. Input a string including the number
2. Copy only the digits from the input string into another string
3. Issue an error message if the input string does not contain exactly 10
digits
4. Output the phone number in standard format
#include "stdafx.h"
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <string>
#include <cctype>
using namespace std;
const int NUM_LENGTH = 10;
string ReadAndValidateUserNumber(string userNumber);
int main()
{
string userNumber;
ReadAndValidateUserNumber(userNumber);
system("PAUSE");
return 0;
}
string ReadAndValidateUserNumber(string userNumber)
{
bool check = false;
while (!check)
{
check = true;
cout << "Please enter a Number: ";
cin >> userNumber;
if (userNumber.length() != NUM_LENGTH)
cout << "The phone number may contain 10 digits only. \n";
else
{
userNumber.insert(0, "(");
userNumber.insert(4, ")");
userNumber.insert(8, "-");
for (int i = 0; i < userNumber.length(); i++)
{
if (isdigit(userNumber[i]))
{
userNumber = NUM_LENGTH;
}
}
}
if (!check)
{
cout << "Invalid Entry! Please try again." << endl;
}
}
return userNumber;
}

You appear to have a logic error.
bool check = false;
while (!check)
{
check = true;
....
if (!check)
{
cout << "Invalid Entry! Please try again." << endl;
}
}
You'll note check never becomes false again. Hence the bottom if statement will never execute and the loop will never iterate more than once as check is always true. You probably want to make
check = true
conditional on the correct format being entered.

The code is in a horrible state. Calm down and focus. There are many problems aside from what you've written. I recommend you to carry the working code to any code reviewing site.
You're doing the check incorrectly, as well as what you're doing after the check is wrong as well.
userNumber = NUM_LENGTH;
This will truncate NUM_LENGTH into char, so you'll have something strange inside userNumber.
This is the right check:
if (!isdigit(userNumber[i]))
{
std::cout << "input should be only numbers\n";
return; //function should return void
}
^^ this is what you should do if you want to break on non number input, if you want to skip non digits, you can use std::copy_if into another string, or tweak the above thing to do it for you. You can also use std::remove_if if you want to remove the non number stuff.
std::string fetched_input;
std::copy_if(userNumber.begin(), userNumber.end(), fetched_input.begin(), std::isdigit);
^^ this will give you the string only with numbers.
Also, you're not doing the check in the correct place. Think about it again.

Related

Unable to detect enter key in C++

Now, before this question gets marked for duplicate. I have already gone through most of the questions and their relative answers of C++. These are the links that I have tried and none of them work for me. It maybe because they are using an older version of C++, and I have the latest version of C++. Here are the links that I have tried:
Detecting ENTER key in C++
https://www.sololearn.com/Discuss/1863352/how-can-i-check-that-user-press-enter-key-in-c
http://www.cplusplus.com/forum/beginner/2624/
https://www.dreamincode.net/forums/topic/398680-detect-enter-key/
Now, with the duplicates out of the way. I am making an expression calculator. So, for example if the user input is: 2+2*6*9/9, then the output should be 14.
The code where I suspect that the problem lies is in:
#include <iostream>
#include <vector>
using std::cout;
using std::cin;
using std::string;
using std::vector;
void clear();
void error(string message);
int main() {
cout << "Enter an expression: ";
double l_Value = 0, r_Value = 0, result = 0, count = 0, previous_number;
char op;
while (cin >> l_Value) { // 1+2*3+6-4/2+3
if (!cin) {
error("Invalid operand entered!");
}
else {
bool is_Error = 0; // false
vector<double> numbers;
numbers.push_back(l_Value);
previous_number = l_Value;
while (cin >> op) {
if (op == '\0') {
break;
}
cin >> r_Value;
switch (op)
{
case '+':
numbers.push_back(r_Value);
previous_number = r_Value;
break;
case '-':
numbers.push_back((-1 * r_Value));
previous_number = (-1 * r_Value);
break;
case '*':
numbers.pop_back(); // take out the number
r_Value *= previous_number;
numbers.push_back(r_Value);
previous_number = r_Value;
break;
case '/':
if (r_Value == 0) {
error("Sorry, division by zero has occured. Please re-evaluate your expression!\n");
is_Error = 1; // true
break;
}
else {
numbers.pop_back(); // take out the number
previous_number /= r_Value;
numbers.push_back(previous_number);
break;
}
}
}
if (!is_Error) {
for (int i = 0; i < numbers.size(); i++) {
result += numbers[i];
}
cout << result << '\n';
}
numbers.clear();
result = 0;
l_Value = 0;
r_Value = 0;
}
cout << "Enter an expression: ";
}
clear();
return 0;
}
None of the links above seemed to work for me.
When I press the Enter key, it expects me to give another input, and that is not supposed to happen. So when I used cin.get() == 'n' or cin.get() == (int)'\n', it expects for another input. But, when I have an 'x' at the end of the expression, it works perfectly fine. So, I need the "cin" operator to help me detect an Enter character at the end of the expression and then terminate the program.
Here, is a sample run of a program with 'x':
[![running as x-terminator][1]][1]
[1]: https://i.stack.imgur.com/ORPQa.png
When I try the above solution such as "cin.get() == '\n':
Then, I thought that maybe it is reading the null character and so, I tried if (op == '\0'):
For the enter key and null character I had to press Ctrl+Z to terminate the program. Please help!
As, mentioned by user #idclev, I already have a string program that works, but I am trying to avoid using string to calculate any expressions! So, if I could detect an enter key pressed using a character datatype that would be great!
I avoided strings to avoid parsing through the text
That argument is moot. What you can read from cin you can also read from a std::string, no difference whatsoever. You just need to add one step:
#include <iostream>
#include <string>
#include <sstream>
int main( ){
std::string x;
std::cin >> x;
if (x == "") {
std::cout << "user pressed enter (and nothing else)";
} else {
double y;
std::stringstream ss{x};
ss >> y;
std::cout << y;
}
}
This will read one std::string. If user only hit enter then the string will be empty. If the user entered something the else branch will be taken and you can extract the number from the string in the same way you did extract the number from cin (via using a std::stringstream).
If you have more than one number in the input you need to use getline to read the string, because cin will (by default) only read till the next whitespace.
Again...
If I used a string, I would have a tough time in extracting single-digit and two-digit or n-number of digits in a string. The double data type does that for me
You can read single-digit or any number of digits from a stringstream in exactly the same way as you read them from cin.
I already made a program with string in it. I was trying to avoid string to see how much faster would it be without string.
It won't be any faster. Constructing the string and the stringstream is maybe in the order of microseconds. A user entering input is in the order of seconds, maybe milliseconds when they are typing very fast.
Your approach cannot work because hitting enter is not considered as a character. Trying to read a character when there is none in the stream will fail. It will not set the character to \n or \r.
On the outer loop, you are trying to read a double, but you keep pressing enter. There is no input to evaluate, so it keeps trying to read a double. You can get out of it by ending the input stream with ^Z, or you can give it any actual content to read, and it will try to make it into a double (which is what your code explicitly told it to wait for).
Basically, when you press enter, it's ignoring it because
http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/
Extracts as many characters as possible from the stream and inserts them into the output sequence controlled by the stream buffer object pointed by sb (if any), until either the input sequence is exhausted or the function fails to insert into the object pointed by sb.
Try experimenting with this to see what is happening.
#include <iostream>
#include <vector>
#include <string>
int main() {
double x;
std::cin >> x;
std::cout << "read this value: " << x << std::endl;
// this is what while or if will look at
bool success = !std::cin.fail();
if (success)
std::cout << "success" << std::endl;
else
std::cout << "failure, loop will exit" << std::endl;
return 0;
}
What you should want (in my opinion) is a function that takes the expression as a string, and returns the result, so you can write unit tests, and make sure the function works. You can use this function with any expression that you can put in a string. It doesn't HAVE to be typed in by a user.
If you want the user to type in the experession, it's a lot easier to just use getline() then pass the string to your function. The big problem with using cin on each variable and character is that the user has no idea which datetype is expected right then. Granted, it's not hard to guess with an expression, but you wrote it and debugged it and still didn't know which cin you were failing to get the right datatype to. (this is normal, btw -- been there, which is why I getline and parse separately)

Accept only Alphabet/Letters for input of a variable, reprompt if not letters

I've been stuck on this for two days. I've searched through page 20 on google and can't figure this out.
I need to accept only alphabetical letters for the input on townName.
I've tried every way of looping (that I can think of or find). Also, I've read that isalpha() only works on characters. However, I've searched for and implemented ways to convert a string from input to characters, I'm just not getting anywhere.
This is my last attempt:
// Input, validate, and set string name of town
cout << "Enter name of town: ";
getline(cin, townName);
cin >> townName; cin.ignore();
while (townName != isalpha()) {
cout << "Enter the town name - alphabet only.";
cin >> townName; }
I'm aware now that is not the proper use of isalpha. I've also tried isalpha(townName), using bools but I need to return a prompt to re-enter if it contains anything other than alpha/white space, and if it's only alpha to continue with main.
You were somewhat on the right track. You need to check each character of your string with isalpha. You might even want to allow for spaces i.e. "New York" etc.? I recommend writing your own method to do this in a loop over your whole input string. Put the whole thing in a while loop and you should be all set to do what you want.
#include <iostream>
#include <string>
#include <cctype>
// check for only alphabetical letters in string (or spaces)
bool lettersOrSpaces(const std::string& str)
{
for (size_t i = 0; i < str.size(); i++)
{
// make sure each character is A-Z or a space
if (! std::isalpha(str[i]) && ! std::isspace(str[i]))
{
return false; ///< at least one "no match"
}
}
return true; ///< all characters meet criteria
}
int main()
{
std::string townName;
std::cout << "Enter name of town: ";
while (std::getline(std::cin, townName) && !lettersOrSpaces(townName))
{
std::cout << "Enter the town name - alphabet only: ";
}
std::cout << "The name of town is: " << townName << std::endl;
return 0;
}

how to allow multiple inputs in case of an incorrect data type entry in cpp?

I have a program which generates random number and asks user to keep guessing it until he/she gets it right. I want it to keep accepting new values even if i incorrectly enter any other data type by handling the error cases.
My problem is that when i am trying to run the below program, as soon i input a character and hit enter, it goes into an infinite loop. I tried using cin.ignore() and cin.clear() but that just makes the program stop after the first entry.
Can anyone please help me understand what is going on and how to achieve the desired output? Thanks in advance.
#include <iostream>
#include <cstdlib>
#include <time.h>
using namespace std;
int main()
{
int secret_num, guess;
srand(time(NULL));
secret_num=rand() % 101 + 0;
cout<<"Enter your guess between 0 and 100: ";
do
{
if(!(cin>>guess))
{
cout<<" The entered value is not an integer"<<endl;
}
else if( isnumber(guess))
{
if(guess>secret_num)
cout<<"Too high";
else if(guess<secret_num)
cout<<"too low";
cout<<endl;
}
}
while(secret_num!=guess);
if((guess==secret_num)| (isnumber(guess)))
{
cout<<"yes the correct number is "<<secret_num<<endl;
}
return 0;
}
Edit: Here is a screenshot of what the output looks like with cin.clear() and cin.ignore(1000,'\n') in my code, when i enter a number after entering character twice.
if (!(cin >> guess))
{
cout << " The entered value is not an integer" << endl;
cin.clear(); // clear must go before ignore
// Otherwise ignore will fail (because the stream is still in a bad state)
cin.ignore(std::numeric_limits<int>::max(), '\n');
}
By default cin.ignore will ignore a single character. If they type more than 1 char, it won't be enough, that's why I've modified it a bit.
if ((guess == secret_num) | (isnumber(guess)))
| is a bitwise operator [OR]
|| is the logical operator [OR]
But I think what you actually want is && (AND)
if ((guess == secret_num) && (isnumber(guess)))
There're several problems.
You should use cin.clear() and cin.ignore() as #José suggested.
What's isnumber()? I guess it's returning false so no hint message (i.e. "Too high" and "too low") is printed out, looks like it stops although it's just waiting the next input. And isnumber() doesn't make sense to me. guess has been declared as an int, it has to be a number, doesn't it?
if((guess==secret_num)| (isnumber(guess))) is unnecessary here. The loop won't end until the user input the correct number, this condition should have been statisfied.
You can use clear and flush
if(!(cin>>guess))
{
cout<<" The entered value is not an integer"<<endl;
cin.clear();
fflush(stdin);
}
This works if you are reading from console. Otherwise you can go with #José answer.
I would change the logic inside your loop as there are some useless tests. This works for me:
#include <iostream>
#include <limits>
#include <cstdlib> // You may take a look at <random> and <chrono>
#include <time.h>
using std::cout;
using std::cin;
int main() {
srand(time(NULL));
int secret_num = rand() % 101;
cout << secret_num << '\n';
cout << "Enter your guess between 0 and 100:\n";
int guess = -1;
do {
cin >> guess;
if ( cin.eof() )
break;
if ( cin.fail() ) {
cout << "The entered value is not an integer, please retry.\n";
// clear the error flag
cin.clear();
// ignore the rest of the line
cin.ignore(std::numeric_limits<int>::max(),'\n');
// clear the value of the variable
guess = -1;
continue;
}
// now we know that guess is a number
if ( guess > secret_num )
cout << "Too high\n";
else if ( guess < secret_num )
cout << "Too low\n";
else {
cout << "Yes the correct number is " << secret_num << std::endl;
break;
}
} while ( true );
return 0;
}

Exiting Loop using Enter(Return Key) C++

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');

Converting char to int when asked to enter an integer and checked with isdigit

So recently, I came across using isdigit as a way to check to see if an entered value for an int is actually an integer, rather than a string or a char.
However, when I wrote a short program to play around with that, the program failed to execute from that point on.
EDIT: I also in the program wanted to take the invalid data and convert it to a different data type.
Here is the code:
#include <iostream>
#include <sstream>
#include <string>
#include <cctype>
using namespace std;
int main()
{
int enterCFN;
char revisit;
int review(0);
cout << "Enter a digit: ";
cin >> enterCFN;
bool y = isdigit(enterCFN);
if (y == false)
{
// This is the data conversion section
revisit = enterCFN;
revisit = review;
cout << review << "\n";
}
else
{
cout << enterCFN << "\n";
}
return 0;
}
Is there anyone who can correct my error and show me what I'm doing wrong?
enterCFN is an int. It stores a number. isdigit() checks if a character represents a number. These are not the same thing: for example 32 is a number but char(32) means ' ' (space).
What you want instead is this:
if (cin >> enterCFN)
That will take the input from the user and check if it is valid all at once. No need for isdigit().
isdigit() checks if a given character is one of 0-9
For validating integer do something like following:
std::cout << "Enter a digit: ";
std::cin >> enterCFN ;
while (1)
{ if ( std::cin >> enterCFN )
{
// good input
break ;
}
else
{
std::cout << "Enter a digit: ";
// clear stream flags set due to bad input
std::cin.clear();
// get rid of the bad input.
// ignore the rest of the line
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
}