formatting phone number in c++ - c++

Please assist, I am trying to format a phone number like (111)111-1111. I have the following code which works but I would like to write much shorter.
int main(){
string phone_number;
cin >> phone_number;
cout<<"(";
for(int i = 0; i < 3; i++) {
cout << phone_number[i];
}
cout << ")";
for(int i = 3; i < 6; i++) {
cout << phone_number[i];
}
cout << "-";
for(int i = 6; i < 10; i++) {
cout << phone_number[i];
}
cout<<endl;
return 0;
}
please assist

Another possibility:
cout << "(" << phone_number.substr(0,3) << ")"
<< phone_number.substr(3,3) << "-" << phone_number.substr(6,4) << endl;

Use string::insert. But since you are taking a string as input, why wouldn't you give the input in format you need. Any how, this is how it can be done with out any loops if you wish to modify the string. In case you don't wish to change the original string then store the modified to a different temporary variable.
string phone_number = "123456789";
phone_number = phone_number.insert( 0, "(" ); // Original string is modified
// Rest can be achieved in similar fashion
cout << phone_number << endl;

for (int i=0; i<10; ++i)
{
if (i == 0) std::cout << '(';
else if (i == 3) std::cout << ')';
else if (i == 6) std::cout << '-';
std::cout << phone_number[i];
}

Probably wouldn't be good to change your data just to format.
string str(phn);
// Format Phone# 1: void function
printf("(%s)%s-%s",
str.substr(0,3).c_str(),
str.substr(3,3).c_str(),
str.substr(6, 4).c_str());
// Format Phone# 2: returns std::string&
stringstream p;
p << "(" << str.substr(0, 3) << ")"
<< str.substr(3, 3) << "-"
<< str.substr(6, 4);
return p.str();

Ignoring the question as to why you want to write this "shorter" ...
printf("(%c%c%c)%c%c%c-%c%c%c%c\n", phone_number[0], phone_number[1], phone_number[2],
phone_number[3], phone_number[4], phone_number[5],
phone_number[6], phone_number[7], phone_number[8],
phone_number[9]);
That being said - your code (nor this) checks to see if there's actually 10 numbers present, or if they're numbers at all. That above all is more important than wanting it "shorter".

Your code is too short, not too long. Any input from the user must always be checked for validity. For instance, what if the used already entered the punctuation, so that phone_number contains "(111)111-1111"? Then your code would output "((11)-)11-1-11" (I think). This is not what you want. At the very least, you must throw out all non-digit characters.

#include <iostream>
using namespace std;
int main(){
string phone_number;
cin >> phone_number;
cout<<"(";
for(int i = 0; i < 3; i++) {
cout << phone_number[i];
}
cout << ")";
for(int i = 3; i < 6; i++) {
cout << phone_number[i];
}
cout << "-";
for(int i = 6; i < 10; i++) {
cout << phone_number[i];
}
cout<<endl;
return 0;
}

Related

Option to print output to screen or given file name (c++)

I would like option 2 to pass the output to a typed file name. However, the program is creating the file but not passing the output to the file. I think just using ostream is fine here, but don't know how to go about it.
void displayTable(int n, char op) {
int printOption;
string outputFileName;
ofstream createOutputFile;
while (true) { //option for print screen or print to file
cout << "Select: \n1) Print on Screen \n2) Print to a file name \nSelection: ";
cin >> printOption;
if (printOption == 1)
break;
else if (printOption == 2){
cout << "Type in the name for the output file." << endl;
cin >> outputFileName;
createOutputFile.open(outputFileName);
break;
}
else
cout << "Please enter a valid number." << endl;
}
int max = getMaxSize(n, op);
cout << setw(max) << op << "|";
for (int i = 1; i <= n; ++i) {
cout << setw(max) << i;
}
cout << endl;
for (int i = 0; i < max; ++i) {
cout << "-";
}
cout << "+";
for (int i = 0; i < n * max; ++i) {
cout << "-";
}
cout << endl;
for (int i = 1; i <= n; ++i) {
cout << setw(max) << i << "|";
for (int j = 1; j <= n; ++j) {
cout << setw(max) << getValue(i, j, op);
}
cout << endl;
}
cout << endl;
createOutputFile.close();
}
You are not printing anything to createOutputFile, everything is being printed to cout instead. That is why to don't see anything in the file, and everything in the console.
The easiest way to solve your issue is to redirect cout to createOutputFile's output buffer, eg:
auto cout_buff = cout.rdbuf();
...
createOutputFile.open(outputFileName);
cout.rdbuf(createOutputFile.rdbuf())
// all cout outputs will now go to the file...
...
cout.rdbuf(cout_buff); // restore when finished...
Otherwise, move your print logic to a separate function that takes an ostream& as a parameter:
void doMyLogic(ostream &os)
{
// print to os as needed...
}
...
if (printOption == 1) {
doMyLogic(cout);
break;
}
if (printOption == 2) {
...
ofstream createOutputFile(outputFileName);
doMyLogic(createOutputFile);
break;
}
...

How do you get cin to only accept numbers from user input? [duplicate]

This question already has answers here:
How to make cin take only numbers
(2 answers)
Closed 6 years ago.
So the requirements for this program is to be able to increment arrays of the same size (size from 5 to 15 indexes) and increment each element in the array by one using for and while loops. The last task is to take values from the first array and put them in reverse order and assign them to the second array.
So everything works as normal, and the program rejects invalid inputs and does not go into an infinite loop. However, the program accepts some inputs that are not wanted.
For example, I would input something like '12 a' or '7 asdfkla;j lasnfg jasklgn asfg' and it would go through. It is interesting too because the code registers only 12 or 7 and completely ignores the rest. I think it is because once it hits a non-integer character, it would stop ignore the rest.
Why is it ignoring the rest of the input? And is there a way to catch this error from going through?
Also, if you see anything that catches your eye, feel free to critique c: I am always looking to improving.
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main() {
srand(time(NULL));
int x;
int j = 0;
bool not_valid = true;
system("color f");
cout << "Program will ask for an input for the size of an array.\n"
<< "With the array size defined, program will generate semi-\n"
<< "true random integers from 0 to 8. First array will then\n"
<< "be assigned to the second in reverse (descending) order.\n\n";
do {
cout << "Enter array size (0 - 15): ";
cin >> x;
if (x >= 5 && x <= 15) {
not_valid = false;
cout << "\nArray size: " << x << endl;
}
else {
cout << "Invalid input.\n\n";
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
} while (not_valid);
int *arr0;
int *arr1;
arr0 = new int[x];
arr1 = new int[x];
for (int i = 0; i < x; i++) {
arr0[i] = rand() % 9;
}
for (int i = 0; i < x; i++) {
arr1[i] = rand() % 9;
}
cout << "\nARRAY 0 (unmodified, for):\n";
for (int i = 0; i < x; i++) {
cout << arr0[i] << "\t";
}
cout << "\n\nARRAY 0 (modified, for):\n";
for (int i = 0; i < x; i++) {
arr0[i]++;
cout << arr0[i] << "\t";
}
cout << "\n\nARRAY 1 (unmodified, while):\n";
for (int i = 0; i < x; i++) {
cout << arr1[i] << "\t";
}
cout << "\n\nARRAY 1 (modified, while):\n";
while (j < x) {
arr1[j]++;
cout << arr1[j] << "\t";
j++;
}
int second = x - 1;
for (int i = 0; i < x; i++) {
arr1[second] = arr0[i];
second--;
}
j = 0;
cout << "\n\nARRAY 1 (array 0, descending):\n";
while (j < x) {
cout << arr1[j] << "\t";
j++;
}
cout << endl << endl;
system("pause");
return 0;
}
Take input in string and then check if it's a number or not.
Example:
#include<iostream>
#include<sstream>
#include <string>
using namespace std;
int main()
{
string line;
int n;
bool flag=true;
do
{
cout << "Input: ";
getline(cin, line);
stringstream ss(line);
if (ss >> n)
{
if (ss.eof())
{
flag = false;
}
else
{
cout << "Invalid Input." << endl;
}
}
}while (flag);
cout << "Yo did it !";
}

Char Array Formatting

I am working on a hangman game where incorrect letter guesses are stored in a char array called wrongletters. Of course, the user begins the game with zero wrongletters, so the wrongletters array remains empty upon declaration. The problem I am having is that when I try to display the wrong letters, the letters are spaced very far to the right because of all the other non-value elements in the array
Intended: (Guessed Letters: A B C D)
Current: (Guessed Letters: (Extra Spaces) A B C D)
Any thoughts? (I am aware game does not function properly yet):
void gameSequence() // Runs the hangman game loop
{
// Local and Global Variable Declaration and Initialization
char guessLetter = ' ';
guessWord = strToUpper(getNextWord());
string maskedWord(guessWord.size(), '_');
char wrongLetters[26] = {};
int numWrongLetters = sizeof(wrongLetters) / sizeof(wrongLetters[0]);
// Input, Process, and Output
cout << "\nLet's PLAY\n\n";
for (int i = 0; i < maskedWord.length(); i++)
cout << maskedWord[i] << " ";
while (incorrectCount < 6)
{
drawHangman(incorrectCount);
cout << "<<<<<<<<<< MAKE A GUESS >>>>>>>>>>\n\n";
cout << "Guessed Letters: ";
for (int i = 0; i < 26; i++)
cout << wrongLetters[i] << " ";
cout << "\n\nEnter a letter to guess: ";
cin >> guessLetter;
cout << endl;
guessLetter = toupper(guessLetter);
for (int i = 0; i < maskedWord.length(); i++)
cout << maskedWord[i] << " ";
if (guessWord.find(guessLetter) != string::npos)
{
for (int i = 0; i < maskedWord.length(); i++)
{
if (maskedWord[i] == guessLetter)
maskedWord[i] = guessLetter;
}
}
else
{
incorrectCount++;
wrongLetters[incorrectCount] = guessLetter;
bubbleSort(wrongLetters, numWrongLetters);
}
if (incorrectCount == 6)
{
drawHangman(incorrectCount);
cout << "Sorry you lose - the word was: " << guessWord << endl << endl;
}
}
incorrectCount = 0;
}
As I understand the array wrongletters contain at the beginning it of the wrong letters guesed so far. So there is no point of print all of it and especially sort all of it.
Hence you should change:
for (int i = 0; i < incorrectCount; i++) // incorrectCount replaced 26
cout << wrongLetters[i] << " ";
...
else
{
incorrectCount++;
wrongLetters[incorrectCount] = guessLetter;
bubbleSort(wrongLetters, incorrectCount+1); // incorrectCount replaced numWrongLetters
}
Otherwise when you sort all of the array the spaces go first before the wrong letters.
Because even if your char sequence is empty, you ask in your loop to display a space after the wrongLetters[i]. Replace the ' ' by endl and you will have
A
B
C
D

C++ adding extra, unwanted characters to a string

I am having a bug that I cannot find a fix for through google searching. I am attempting to make a text based version of the game Mastermind. I am using a string the is set from an array of chars as the criteria for a while loop. When the string is equal to "****" the game is supposed to tell the player that they won and exit, but for some reason a ^A is being added on to the end of the string that is being checked, even though it is not in the char array.
Here is the function that sets the char array and returns a string from that array:
string check(int guess[4], int num[4]) {
char hints[4];
cout << " ";
for (int i = 0; i < 4; i++) {
if (guess[i] == num[i]) {
hints[i] = '*';
cout << "*";
}
else {
for (int x = 0; x < 4; x++) {
if (guess[i] == num[x]) {
cout << "+";
}
}
}
if (guess[i] != num[i]) {
hints[i] = ' ';
}
}
string hint(hints);
cout << endl;
cout << hint << endl;
return hint;
}
And here is the function checking the value of the string:
while (hints.compare("****") != 0) {
if (guessCount == 5) {
break;
}
cout << "Guess?: ";
cin >> guess;
intToArray(guess, guessArr);
hints = check(guessArr, nums);
cout << hints << endl;
guessCount++;
}
if (hints.compare("****") == 0) {
cout << "You win! The number was: ";
for (int i = 0; i < 4; i++) {
cout << nums[i];
}
}
You haven't null-terminated the hints array, so you are getting extra garbage that is lying around on the stack in your string.
You could let the hint string know how long it is when you are constructing it.
string hint(hints, 4);
cout << endl;
cout << hint << endl;

c++ toupper() to compare two strings

I have created a set of algorithms that takes an input of a string vector, checks whether any of the strings occur more than once: if so erases all additional occurrences of the string from the vector, then outputs the new, 'lighter' array without the redundancies.
It works great except now I am to make it case-insensitive; I am attempting to simply add the toupper() std function to the == comparison statement, however it does not seem to work.
I have a more familiar background with Java and am trying to learn C++.
Can someone please show me how to correct my syntax?
// Output old list.
cout << endl << "==========\nOld list:\n==========";
for (int i = 0; i < count; i++) {
cout << endl << list[i];
}
cout << endl << endl;
// Check uniqueness.
for (int i = 0; i < count; i++)
for (int j = i+1; j < count; j++) {
if (toupper(list[i]) == toupper(list[j])) {
list[j] = "";
count--;
}
}
// Output new list.
cout << endl << "==========\nNew list:\n==========";
for (int i = 0; i < count; i++) {
cout << endl << list[i];
}
cout << endl << endl;
Your loop leaves "holes" in the list array vector, but the size of the array vector does not change (but you decrease your upper bound count)
There are probably many other alternatives, but if you don't want to modify it much, probably you need in an addtional loop to copy non-empty elements from the list array into a new array
Edit: integrating some of the answers
First we're going to have a function to do the toUpper (this is modified from #Jim22150)
std::string stringToUpper(const std::string &input) {
std::string toBeModified=input;
std::transform(toBeModified.begin(), toBeModified.end(), toBeModified.begin(), ::toupper);
return toBeModified;
}
Now, we must not leave holes, so we should use erase (as #Scott Christopher Stauffe indicated):
// Output old list.
cout << endl << "==========\nOld list:\n==========";
for (int i = 0; i < count; i++) {
cout << endl << list[i];
}
cout << endl << endl;
// Check uniqueness.
for (int i = 0; i < count; i++)
for (int j = i + 1; j < count; j++) {
if(stringToUpper(list[i]) == stringToUpper(list[j])) {
list.erase(j,1);
count--;
}
}
}
// Output new list.
cout << endl << "==========\nNew list:\n==========";
for (int i = 0; i < count; i++) {
cout << endl << newlist[i];
}
cout << endl << endl;
#DaveS, thanks Dave I will try that; it looks clean and short. However, I found dirtier solution using transform and making a duplicate of the old vector.
// Output old list.
cout << endl << "==========\nOld list:\n==========";
for (int i = 0; i < count; i++) {
cout << endl << list[i];
}
cout << endl << endl;
// Check uniqueness.
for (int i = 0; i < count; i++)
for (int j = i + 1; j < count; j++) {
std::transform(list[i].begin(), list[i].end(), list[i].begin(), ::toupper);
std::transform(list[j].begin(), list[j].end(), list[j].begin(), ::toupper);
if (list[i] == list[j]) {
newlist[j] = "";
count--;
}
}
// Output new list.
cout << endl << "==========\nNew list:\n==========";
for (int i = 0; i < count; i++) {
cout << endl << newlist[i];
}
cout << endl << endl;
If you want to handle C++ strings as easily as Java strings, then the Boost String Algorithms Library is the way to go. Installing Boost may be a bit hard for a newbie C++ programmer (although it's a breeze compared to many other C++ libraries), but it pays off.
Your problem will essentially be reduced to this:
boost::algorithm::to_upper_copy(list[i]) == boost::algorithm::to_upper_copy(list[j])
I just did a quick google of toupper and I didn't find any string versions of it. The only standard touppper() I have seen is int toupper(int c); - that means you can only use it to compare individual characters! Have you tried stricmp()?
if ( 0 == _stricmp(list[i], list[j]) ) {
list[j] = "";
count--;
}
Depending on your compiler you may or may not have this function at your disposal.
First of all,
list[j] = ""; // should never work.
You can remove a char by using erase.
list.erase(j, 1);
Alternatively, to avoid this altogether, you could use a temporary "builder" string and just push_back chars to it when needed.