Reading digits and converting to words - c++

I'm new to c++ and I have to write a program that takes a user 4-digit number and convert it to words i.e. 7238 would be wrote as seven two three eight. Yet it writes every number as unknown. Any advice for a noob would be greatly appreciated.
#include iostream
using namespace std;
int main() {
char number;
cout << "Please enter a 4 digit number: ";
cin >> number;
switch(number){
case 1 :
cout<< "one";
break;
case 2 :
cout<< "two";
break;
case 3 :
cout<< "three";
break;
case 4 :
cout<< "four";
break;
case 5 :
cout<< "five";
break;
case 6 :
cout<< "six";
break;
case 7 :
cout<< "seven";
break;
case 8 :
cout<< "eight";
break;
case 9 :
cout<< "nine";
break;
case 0 :
cout<< "zero";
break;
default :
cout << "UNKNOWN.";
}
}

Sounds like homework but here are some tips. Change your number variable to type of int You can break the number out into individual variables with division and modulus. I would stuff those into an integer array.
int array[4];
arr[0] = (number / 1000) % 10; // Thousands
....... // You do the hundreds and tens
arr[3] = (number % 10); // Ones
Then use a loop around your switch statement where your counter is less than 4 (the length of the array). Make sure to increase your counter at the end of each loop. Oh, and it's #include <iostream>.

With to_string and range based for:
#include <iostream>
#include <string>
using namespace std;
int main()
{
int number;
cout << "Enter the number: ";
cin >> number;
string strnum = to_string(number);
for (auto c : strnum)
{
switch (c)
{
case '0': cout << "zero "; break;
case '1': cout << "one "; break;
case '2': cout << "two "; break;
case '3': cout << "three "; break;
case '4': cout << "four "; break;
case '5': cout << "five "; break;
case '6': cout << "six "; break;
case '7': cout << "seven "; break;
case '8': cout << "eight "; break;
case '9': cout << "nine "; break;
default: cout << "non-digit"; break;
}
}
return 0;
}

You need to put ascii values in your case statements. Currently you are comparing the ascii values for digits with numbers 0 - 9.
Values can be found here : http://www.asciitable.com/

Your variable is of type char. A char stores a character, usually ASCII encoded. If the user inputs a '1', for example, that would usually translate to an integer value of 49, not 1. Either read into an int or change your case labels to use character literals:
case '1':
cout << "one";
break;
You could then use a loop to read multiple digits.

Related

ASCII Strength Game will not calculate "Bot" word value

I'm making a game that tests the ASCII strength of a user versus a bot. (There is also a 2 player mode but that's working fine.) The full description is given at the top of my .cpp file. As a basic breakdown, the bot opens a txt file with 500 common four letter words and inserts them into a size 500 array. It then randomly generates a number to pick a random one, and then goes through the process of tovalue() to recieve its ASCII value, where in tovalue() runs through chartoint() four times, one for each character of the word. My issue is that the program calculates the ASCII value perfectly fine of the user generated word, but always returns 0 (0000) for the botword, no matter what the word.
I've tried a few iterations of the generateword() function including using a vector but always get the same resutls. I've done a lot of digging about this and haven't quite found any solutions, although I suspect that the chartoint() function could be better optimized, just not sure how to impliment any better solutions for this specific case. Also, don't think the problem is with chartoint() since it works fine for user input, but I'm pretty sure the problem is with generateword(). Suggestions for making chartoint() would be helpful, but its not my main priority right now since I just need the program to 100% work first. Also, I've confirmed that all of the words in my .txt file are all caps and only four characters per line.
// Write the code for a game called “ASCII Strength” of a four-letter word selected by Player 1
// followed by a four-letter word selected by Player 2. The result would be the sum
//of the ASCII value of each of the letters of the selected words and whoever has higher sum (called ASCII strength) wins.
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
#include <cstdlib>
#include <ctime>
using namespace std;;
int chartoint(char a) {
switch (a) {
case 'A':
return 1;
break;
case 'B':
return 2;
break;
case 'C':
return 3;
break;
case 'D':
return 4;
break;
case 'E':
return 5;
break;
case 'F':
return 6;
break;
case 'G':
return 7;
break;
case 'H':
return 8;
break;
case 'I':
return 9;
break;
case 'J':
return 10;
break;
case 'K':
return 11;
break;
case 'L':
return 12;
break;
case 'M':
return 13;
break;
case 'N':
return 14;
break;
case 'O':
return 15;
break;
case 'P':
return 16;
break;
case 'Q':
return 17;
break;
case 'R':
return 18;
break;
case 'S':
return 19;
break;
case 'T':
return 20;
break;
case 'U':
return 21;
break;
case 'V':
return 22;
break;
case 'W':
return 23;
break;
case 'X':
return 24;
break;
case 'Y':
return 25;
break;
case 'Z':
return 26;
break;
}
return 0;
}
int tovalue(string input) {
int first = chartoint(input[0]);
int second = chartoint(input[1]);
int third = chartoint(input[2]);
int fourth = chartoint(input[3]);
cout << first << second << third << fourth; // EXISTS TO TEST CALCULATION
int value = first + second + third + fourth;
return value;
}
string generateword() {
string arr[500];
ifstream file("words.txt");
if (file.is_open())
{
for (int i = 0; i < 500; i++) {
string temp;
getline(file, temp);
arr[i] = temp;
}
file.close();
}
else
{
cout << "Error: Unable to open file.";
exit(0);
}
srand(time(0));
int random_index = rand() % 500;
string random_word = arr[random_index];
return random_word;
}
int main()
{
cout << "Welcome to ASCII strength, a game where the strongest word wins!";
cout << "\nTo play, you must enter a four letter word. The program will calculate the 'ASCII strength' of your word and compare it to your opponent.";
cout << "\nWhoever has the higher sum will win!";
char another;
another = 'y';
while (another == 'y' || another == 'Y') {
cout << "\nWould you like to play against a friend, or against a bot? (F/B)";
char mode;
cin >> mode;
if (mode == 'F' || mode == 'f') {
cout << "\nPlayer 1, please input your four letter word in all caps: ";
string answer1;
cin >> answer1;
int value1;
value1 = tovalue(answer1);
cout << "\nPlayer 2, please input your four letter word in all caps: ";
string answer2;
cin >> answer2;
int value2;
value2 = tovalue(answer2);
if (value1 > value2) {
cout << "\nPlayer 1 wins!";
}
else if (value2 > value1) {
cout << "\nPlayer 2 wins!";
}
else if (value1 == value2) {
cout << "\nTie!";
}
}
else if (mode == 'B' || mode == 'b') {
cout << "\nPlease input your four letter word in all caps: ";
string answer;
cin >> answer;
int valueanswer;
valueanswer = tovalue(answer);
string botword;
botword = generateword();
cout << "\nThe bot generates a random word based on a list of popular four letter words.";
cout << "\nThe bot has generated this word: " << botword;
int valuebot;
valuebot = tovalue("botword");
cout << valueanswer << " " << valuebot; // THIS EXISTS PURELY TO TEST WHETHER THE VALUES ARE PROPERLY CALCULATING
if (valueanswer > valuebot) {
cout << "\nYou win!";
}
else if (valuebot > valueanswer) {
cout << "\nThe bot wins!";
}
else if (valueanswer == valuebot) {
cout << "\nTie!";
}
}
cout << "\nWould you like to start a new game? (y/n)";
cin >> another;
}
}
Your problem is this line:
valuebot = tovalue("botword");
Since all characters in "botword" are lowercase, you get all 0 score. You probably meant to write
valuebot = tovalue(botword);

C++ Newbie: Why don't these nested loops work for this program?

I'm in the middle of taking an online C++ course, and I've been having issues with this homework problem. I tried reaching out to my professor twice, but he hasn't responded. I've sought out many solutions, but since I'm new in the course, many of the solutions involve using techniques I haven't learned yet (like character arrays.) I can get the conversion program to work, but I want the program to allow to process as many user inputs as the user wants.
When I run the program, the program accepts my first input that is 'y' or 'Y' to run the program. It then will ask for a string to convert to the telephone number. This works. However, I need the program to ask the user if they want to run the program again to convert another string to a telephone number or to terminate the program.
I put in another cin at the end of the first while loop to prompt for another input, but it gets skipped over everytime and keeps doing the while loop.
Question: Why is the last prompt to repeat the program get skipped every time I've run it? What am I missing?
Here's the problem and what I've done so far:
Problem:
To make telephone numbers easier to remember, some companies use
letters to show their telephone number. For example, using letters,
the telephone number 438-5626 can be shown as GET LOAN.
In some cases, to make a telephone number meaningful, companies might
use more than seven letters. For example, 225-5466 can be displayed as
CALL HOME, which uses eight letters. Instructions
Write a program that prompts the user to enter a telephone number
expressed in letters and outputs the corresponding telephone number in
digits.
If the user enters more than seven letters, then process only the
first seven letters.
Also output the - (hyphen) after the third digit.
Allow the user to use both uppercase and lowercase letters as well as
spaces between words.
Moreover, your program should process as many telephone numbers as the
user wants.
My code so far:
#include <iostream>
using namespace std;
int main()
{
char letter, runLetter;
int counter = 0;
cout << "Enter Y/y to convert a telephone number from letters to digits"
<< endl;
cout << "Enter any other key to terminate the program." << endl;
cin >> runLetter;
while (runLetter == 'y' || runLetter == 'Y')
{
cout << "Enter in a telephone number as letters: " << endl;
while (cin.get(letter) && counter < 7 )
{
if (letter != ' ' && letter >= 'A' && letter <= 'z')
{
counter++;
if (letter > 'Z')
{
letter = (int)letter-32;
}
if (counter == 4)
cout << "-";
switch (letter)
{
case 'A':
case 'B':
case 'C':
{
cout << "2";
break;
}
case 'D':
case 'E':
case 'F':
{
cout << "3";
break;
}
case 'G':
case 'H':
case 'I':
{
cout << "4";
break;
}
case 'J':
case 'K':
case 'L':
{
cout << "5";
break;
}
case 'M':
case 'N':
case 'O':
{
cout << "6";
break;
}
case 'P':
case 'Q':
case 'R':
case 'S':
{
cout << "7";
break;
}
case 'T':
case 'U':
case 'V':
{
cout << "8";
break;
}
case 'W':
case 'X':
case 'Y':
case 'Z':
{
cout << "9";
break;
}
default:
break;
}
}
}
cout << endl;
cout << "To process another telephone number, enter Y/y" << endl;
cout << "Enter any other key to terminate the program." << endl;
cin >> runLetter;
}
cout << "Goodbye. " << endl;
return 0;
}
Thanks in advance for any help. I know this might be an easy solution, but I've been tinkering with this program for a couple of days now.
Tried moving the last user prompt in and out of each if/else structure and different while loops. Not sure what I can do to make the program take a new input after the first iteration.
A very good hint to your problem is the comment from #AlanBirtles. Also I know you are a beginner and you may not know about std::string but you should use it because you are learning C++ not C. in a nutshell, it is a C++ way of dealing with char arrays, also better than just that.
Here is your code with minimum changes to do what you are looking for. The main changes is the use of std::string, the use of std::getline and the definition of the counter inside the while loop.
#include <iostream>
#include <string>
using namespace std;
int main()
{
char letter;
std::string runLetter;
std::string number;
cout << "Enter Y/y to convert a telephone number from letters to digits"
<< endl;
cout << "Enter any other key to terminate the program." << endl;
std::getline( std::cin, runLetter);
while (runLetter == "y" || runLetter == "Y")
{
int counter = 0;
cout << "Enter in a telephone number as letters: " << endl;
std::getline(std::cin, number);
for (int i = 0; i < number.size(); i++)
{
letter = number[i];
if (counter < 7)
if (letter != ' ' && letter >= 'A' && letter <= 'z')
{
counter++;
if (letter > 'Z')
{
letter = (int)letter - 32;
}
if (counter == 4)
cout << "-";
switch (letter)
{
case 'A':
case 'B':
case 'C':
{
cout << "2";
break;
}
case 'D':
case 'E':
case 'F':
{
cout << "3";
break;
}
case 'G':
case 'H':
case 'I':
{
cout << "4";
break;
}
case 'J':
case 'K':
case 'L':
{
cout << "5";
break;
}
case 'M':
case 'N':
case 'O':
{
cout << "6";
break;
}
case 'P':
case 'Q':
case 'R':
case 'S':
{
cout << "7";
break;
}
case 'T':
case 'U':
case 'V':
{
cout << "8";
break;
}
case 'W':
case 'X':
case 'Y':
case 'Z':
{
cout << "9";
break;
}
default:
break;
}
}
}
cout << endl;
cout << "To process another telephone number, enter Y/y" << endl;
cout << "Enter any other key to terminate the program." << endl;
std::getline(std::cin, runLetter);
}
cout << "Goodbye. " << endl;
return 0;
}
I found the following errors in your code:
You do not reset the variable counter to 0 in the second loop iteration, so that counter has the value 7 in the entire second loop iteration, which causes the inner while loop not to be entered. This bug should be clearly visible when running your program line by line in a debugger while monitoring the values of all variables.
You always read exactly 7 characters from the user per loop iteration, which is wrong. You should always read exactly one line per loop iteration. In other words, you should read until you find the newline character. You can ignore every character after the 7th letter, but you must still consume them from the input stream, otherwise they will be read in the next loop iteration(s), which you do not want. However, this does not mean that you can simply ignore everything after the 7th character, because the number of characters is not necessarily identical to the number of letters. For example, if a 7 character string has one space character, then it only has 6 letters. As stated in the task description, the user should be allowed to enter spaces in the string.

How do you accept multiple values for a switch case? [duplicate]

This question already has answers here:
How do I select a range of values in a switch statement?
(18 answers)
Closed 2 years ago.
How does one accept more than one value for a single case in C++? I know you can make a range of values for one case (e.g. case 1..2) in some other languages, but it doesn't seem to be working in C++ on Xcode.
int main() {
int input;
cin >> input;
switch (input) {
case 1:
cout << "option 1 \n";
break;
case 2..3: //This is where the error occurs
cout << "option 2 and 3 \n";
break;
default:
break;
}
return 0;
}
The program shows an error saying "Invalid suffix '.3' on floating constant" where the range is.
You can "fall through" by having sequential case statements without a break between them.
switch (input) {
case 1:
cout << "option 1 \n";
break;
case 2:
case 3:
cout << "option 2 and 3 \n";
break;
default:
break;
}
Note that some compilers support range syntax like case 50 ... 100 but this is non-standard C++ and will likely not work on other compilers.
You could simply do:
switch (input) {
case 1:
cout << "option 1 \n";
break;
case 2: [[fallthrough]]
case 3:
cout << "option 2 and 3 \n";
break;
default:
break;
}
Note that case 2 ... 3 is called case ranges, and is a non-standard gcc extension that you could use.
You can't do a range of values, but you can do multiple values:
switch (input) {
case 1:
cout << "option 1 \n";
break;
case 2: case 3: case 4:
cout << "option 2 or 3 or 4\n";
break;
default:
break;
}
You need to use spaces between them with three(...)
int main() {
int input;
cin >> input;
switch (input) {
case 1:
cout << "option 1 \n";
break;
case 2 ... 3: //This is where the error occurs
cout << "option 2 and 3 \n";
break;
default:
break;
}
return 0;
}

I think there's a slight mistake that my C++ textbook is giving me about switch statement

#include <iostream>
using namespace std;
int main()
{
int grade;
int aCount;
int bCount;
int cCount;
int dCount;
int fCount;
cout << "Enter the letter grades." << endl
<< "Enter the EOF character to end input." << endl;
while ((grade = cin.get()) != EOF)
{
switch (grade)
{
case 'A':
case 'a':
aCount++;
break;
case 'B':
case 'b':
bCount++;
break;
case 'C':
case 'c':
cCount++;
break;
case 'D':
case 'd':
dCount++;
break;
case 'F':
case 'f':
fCount++;
break;
case '\n':
case '\t':
case ' ':
break;
default:
cout << "Incorrect letter grade entered." << "Enter a new grade." << endl;
break;
}
}
cout << "\n\nNumber of students who received each letter grade:"
<< "\nA: " << aCount
<< "\nB: " << bCount
<< "\nC: " << cCount << "\nD: " << dCount << "\nF: " << fCount << endl;
system("PAUSE");
return 0;
}
This is an exact code provided by my C++ textbook. While I was practicing these switch statement codes by copying these codes then compile it, my Visual Studio 2010 express keep gives me an error saying that "aCount is being used without assigned..." same applies to fCount. This program should read any letter from A to F from a keyboard then increment whatever letter that was recognized. I think there should be cin>>grade somewhere in the codes but I don't find it. By the way, can "cin.get()" could work as cin>>grade??
When you are declaring your variables try giving them the value of 0 like this:
int grade = 0;
int aCount = 0;
int bCount = 0;
int cCount = 0;
int dCount = 0;
int fCount = 0;
This will ensure that you are in fact assigning a value to the variable before it is being used.
Then try to run it, I bet it works!
It is advisable for you to initialize your variables being using it. Some compiler will not even give you a warning before compilation, but assigns some "garbage values" to your un-initialize variables.
Initializing your variables to 0 is suffice in this scenario (Like what other user mentioned).
int grade=0;
int aCount=0;
int bCount=0;
int cCount=0;
int dCount=0;
int fCount=0;
By the way, can "cin.get()" could work as cin>>grade??
That depends on how you want to use it. cin.get can be used to extract a:
single character
multiple characters and store them as c-string (char array) or
store them into a stream buffer object
from the input stream.
You may realize cin.get can't accept numbers, so if you are accepting input of characters or string, it is fine. But in future, if you want it to accept numbers, just use cin >> number
An example on using cin.get()
char cStr[50];
cin.get(cStr,5); //It will take n-1 characters
cout << cStr;
//Input: abcde
//Output: abcd

Getting a program to start over and get a new value?

I am working with a program which requires a value to put in a variable and do some stuff on it. The problem is that I want the program to start over again and ask the user for a new value to process the new value again.
For example look at this code, which requires a number as a grade to rate it. When the processing was done I want the program to ask for a new grade ( next student for instance ).
#include <iostream.h>
int main (int argc, const char * argv[])
{
int n;
cout<< " Please Enter your grade : " ;
cin>>n;
switch (n/10) {
case 10: cout<< " A+ : Great! ";
case 9:
break;
case 8: cout<< " A : Very Good ";
break;
case 7: cout<< " B : Good " ;
break;
case 6:
case 5:
case 4:
case 3:
case 2:
case 1:
case 0: cout<< " Failed ";
break;
default:
break;
}
return 0;
}
What you need is a while loop
int main (int argc, const char * argv[])
{
int n;
while(1) {
cout<< " Please Enter your grade : " ;
cin>>n;
switch (n/10) {
case 10: cout<< " A+ : Great! ";
case 9:
case 8: cout<< " A : Very Good ";
break;
case 7: cout<< " B : Good " ;
break;
case 6:
case 5:
case 4:
case 3:
case 2:
case 1:
case 0: cout<< " Failed ";
break;
default:
break;
}
cout<<"do you wish to continue?(y/n)";
cin>>some_declared_variable;
if (some_declared_variable == 'n')
break; //hopefully this will break the infinite loop
}
return 0;
}