I'm working on a fun random ICAO translator program and I'm almost done with it but I'm having one little problem. How do I go about splitting a string by each character? For example the output I want is;
The word mike translated in the ICAO alphabet is:
m: Mike
i: Indiana
k: Kilo
e: Echo
So far I just get;
The word mike translated in the ICAO alphabet is:
Mike
Indiana
Kilo
Echo
Apparently my post is mostly code and I must add more detail so I'm adding this sentence to hopefully satisfy the requirements. Also the translation should be right on top of each other and not one extra space down. I'm having problems with that and idk how to fix that.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string word = " ", phonetic;
int count = 0;
cout << "Enter a word: ";
cin >> word;
while(count < word.length())
{
switch(word.at(count))
{
case 'A': case 'a': phonetic += " Alpha\n";
break;
case 'B': case 'b': phonetic += " Bravo\n";
break;
case 'C': case 'c': phonetic += " Charlie\n";
break;
case 'D': case 'd': phonetic += " Delta\n";
break;
case 'E': case 'e': phonetic += " Echo\n";
break;
case 'F': case 'f': phonetic += " Foxtrot\n";
break;
case 'G': case 'g': phonetic += " Golf\n";
break;
case 'H': case 'h': phonetic += " Hotel\n";
break;
case 'I': case 'i': phonetic += " Indiana\n";
break;
case 'J': case 'j': phonetic += " Juliet\n";
break;
case 'K': case 'k': phonetic += " Kilo\n";
break;
case 'L': case 'l': phonetic += " Lima\n";
break;
case 'M': case 'm': phonetic += " Mike\n";
break;
case 'N': case 'n': phonetic += " November\n";
break;
case 'O': case 'o': phonetic += " Oscar\n";
break;
case 'P': case 'p': phonetic += " Papa\n";
break;
case 'Q': case 'q': phonetic += " Quebec\n";
break;
case 'R': case 'r': phonetic += " Romeo\n";
break;
case 'S': case 's': phonetic += " Sierra\n";
break;
case 'T': case 't': phonetic += " Tango\n";
break;
case 'U': case 'u': phonetic += " Uniform\n";
break;
case 'V': case 'v': phonetic += " Victor\n";
break;
case 'W': case 'w': phonetic += " Whiskey\n";
break;
case 'X': case 'x': phonetic += " X-Ray\n";
break;
case 'Y': case 'y': phonetic += " Yankee\n";
break;
case 'Z': case 'z': phonetic += " Zulu\n";
break;
default: cout << "You did not enter a name" << endl;
}
count++;
}
cout << "The word "<< word <<" in the ICAO alphabet is:\n"
<< phonetic << endl;
return 0;
}
To go through a string, you can simply use iterators:
std::string test_string = "test";
for( auto const& character : test_string )
{
std::cout << character << "\n";
}
The whole program can be simplified, by using a map:
// Example program
#include <iostream>
#include <map>
#include <string>
char to_lower(char ch)
{
return static_cast<char>(std::tolower(static_cast<unsigned char>(ch)));
}
int main()
{
const std::map<char, std::string> phonetic_alphabet =
{
{'a', "Alpha"}
,{'b', "Bravo"}
,{'c', "Charlie"}
,{'d', "Delta"}
,{'e', "Echo"}
,{'f', "Foxtrot"}
,{'g', "Golf"}
,{'h', "Hotel"}
,{'i', "Indiana"}
,{'j', "Julia"}
,{'k', "Kilo"}
,{'l', "Lima"}
,{'m', "Mike"}
,{'n', "November"}
,{'o', "Oscar"}
,{'p', "Papa"}
,{'q', "Quebec"}
,{'r', "Romeo"}
,{'s', "Sierra"}
,{'t', "Tango"}
,{'u', "Uniform"}
,{'v', "Victor"}
,{'w', "Whiskey"}
,{'x', "X-Ray"}
,{'y', "Yankee"}
,{'z', "Zulu"}
};
std::cout << "Enter a word: ";
std::string word;
std::cin >> word;
for( auto const& c : word )
{
const char lower_c = to_lower(c);
if( phonetic_alphabet.find(lower_c) != phonetic_alphabet.end() )
{
std::cout << phonetic_alphabet.at(lower_c) << " ";
}
else
{
std::cout << c << " ";
}
}
}
If I understand your post correctly, you don't want to split a string but to iterate through its characters.
In C++11:
for (char& c : word) {
// switch (c)
}
The answer of infinitezero is totally ok and probably the best solution in this case.
I would like to addtionally show a loop-less solution, also based on a std::unordered_map and able to read a complete sentence.
The basic idea is: Based on the requirement to transform single characters to ICAOwords, I decided to use a dedicated function for this purpose: std::transform. You may see the documentation here
Please see the additional / alternative solution below:
#include <iostream>
#include <unordered_map>
#include <string>
#include <algorithm>
#include <iterator>
int main()
{
// Preinitialize an unordered map
std::unordered_map<int, std::string> alpha =
{
{'a', "Alpha"},{'b', "Bravo"},{'c', "Charlie"},{'d', "Delta"},{'e', "Echo"},{'f', "Foxtrot"},{'g', "Golf"},
{'h', "Hotel"},{'i', "Indiana"},{'j', "Julia"},{'k', "Kilo"},{'l', "Lima"} ,{'m', "Mike"},{'n', "November"},
{'o', "Oscar"},{'p', "Papa"},{'q', "Quebec"},{'r', "Romeo"},{'s', "Sierra"},{'t', "Tango"},{'u', "Uniform"},
{'v', "Victor"},{'w', "Whiskey"},{'x', "X-Ray"},{'y', "Yankee"},{'z', "Zulu"}};
// Read word form user
if (std::string word; std::getline(std::cin, word)) {
// Show output to user
std::cout << "\n\n" << word << " --> ";
// Convert and show
std::transform(word.begin(), word.end(), std::ostream_iterator<std::string>(std::cout, " "),
[&](const char c) { return (isalpha(c) ? alpha[tolower(c)] : ""); });
}
return 0;
}
Related
Code for a blackjack card counting program.
the issue is that it does not exit the while loop upon receiving no cin input from the user.
for example)
User would input x chars and then hit enter to exit the while loop.
#include<iostream>
using namespace std;
int main(){
int count = 0;
char currcard;
cout<<"Enter cards seen on table: "<<endl;
while (cin>>currcard)
{
switch (currcard)
{
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
count++;
break;
case '7':
case '8':
case '9':
break;
case 'A':
case 'J':
case 'Q':
case 'K':
count--;
break;
default:
cout<<"Invalid Entry";
break;
}
}
cout <<"Current count: "<< count << endl;
//user enter cards seen on table and if below 7 increment
//based on count the program returns if you should hit or quit
return 0;
}
Expecting program to exit when enter is hit by user
You can use cin.get() like this.
while (cin>>currcard)
{
// your logic
if (cin.get() == '\n') {
break;
}
}
In this way, your input is supposed to be something like 1 2 3 4 A J Q ending with Enter.
EDIT
As OP wants undetermined length of input, I suggest to switch the input itself from char to std::string.
This way access is gained to more intuitive and effective I\O operations:
#include <iostream> // std::cin, cout, endl
#include <string> // std::string: can omit this line
#include <cctype> // isspace(): can omit
int main(){
int count = 0;
std::string currcard{""};
std::cout << "Enter cards seen on table: "<< std::endl;
std::getline(std::cin, currcard);
for (char c : currcard) {
if (isspace(c))
continue;
switch (c) {
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
++count;
break;
case '7':
case '8':
case '9':
break;
case 'A':
case 'J':
case 'Q':
case 'K':
--count;
break;
default:
//std::cout << "Invalid Entry\n";
break;
}
}
std::cout <<"Current count: "<< count << std::endl;
//user enter cards seen on table and if below 7 increment
//based on count the program returns if you should hit or quit
return 0;
}
Notice I have added a check for white spaces, and removed the message for invalid entries: both simply get ignored. But if needed that line can be uncommented.
Old solution
You can use cin.getline() as suggested in the comments, in conjunction with a flag that triggers exit from the loop once three inputs are given:
#include <iostream>
int main(){
static int count = 0, flag = 0;
char currcard;
std::cout << "Enter cards seen on table: "<< std::endl;
while(std::cin.getline(&currcard, 3)){
switch (currcard)
{
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
++count;
break;
case '7':
case '8':
case '9':
break;
case 'A':
case 'J':
case 'Q':
case 'K':
--count;
break;
default:
std::cout << "Invalid Entry\n";
--flag;
break;
}
++flag;
if (flag == 3)
break;
}
std::cout <<"Current count: "<< count << std::endl;
//user enter cards seen on table and if below 7 increment
//based on count the program returns if you should hit or quit
return 0;
}
There is also a flag decrement for invalid entries.
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.
new here, trying to figure out how to repeat my program. I need to understand how to insert a loop, i think a "do while" loop will work for this, but I am unsure because I have tried a few places of insertion and cannot get it to work right.
So my program is a telephone program, I am sure everyone here has done this in school, I am learning to do this and this is the part that I am confused on. My code is below.
I just need to make it possible for the user to keep entering phone numbers, over and over again.
I feel like I should be inserting a "do" before line14 "for (counter = 0...
Then insert the "while" portion at line 94 between the brackets. For some reason, that doesn't work for me and I am now stumped.
NOTE This is an assignment for school, so please explain to me rather than just show me. Thanks for everyones help.
#include <iostream>
using namespace std;
int main() {
int counter;
char phoneNumber;
cout << "\nEnter a phone number in letters only." << endl;
for (counter = 0; counter < 7; counter++)
{
cin >> phoneNumber;
if (counter == 3)
cout << "-";
if (phoneNumber >= 'A' && phoneNumber <= 'Z'
|| phoneNumber >= 'a' && phoneNumber <= 'z')
switch (phoneNumber)
{
case 'A':
case 'a':
case 'B':
case 'b':
case 'C':
case 'c':
cout << 2; // keypad starts with 2 for letters ABC, abc
break;
case 'D':
case 'd':
case 'E':
case 'e':
case 'F':
case 'f':
cout << 3; //for letter DEF, def
break;
case 'G':
case 'g':
case 'H':
case 'h':
case 'I':
case 'i':
cout << 4; //for letters GHI, ghi
break;
case 'J':
case 'j':
case 'K':
case 'k':
case 'L':
case 'l':
cout << 5; //for letter JKL, jkl
break;
case 'M':
case 'm':
case 'N':
case 'n':
case 'O':
case 'o':
cout << 6; //for letters MNO, mno
break;
case 'P':
case 'p':
case 'Q':
case 'q':
case 'R':
case 'r':
case 'S':
case 's':
cout << 7; //for letters PQRS, pqrs
break;
case 'T':
case 't':
case 'U':
case 'u':
case 'V':
case 'v':
cout << 8; //for letters TUV, tuv
break;
case 'W':
case 'w':
case 'X':
case 'x':
case 'Y':
case 'y':
case 'Z':
case 'z':
cout << 9; //for letters WXYZ, wxyz
break;
}
}
return 0;
}
As already said by pb772 an infinite loop of type
do { //Stuff you'd like to do } while(1);
would be fine, especially since it's a school assignment, but not ideal as always stated by pb772.
I've seen advises to cycle a finite number of times and then exit but I would instead do something like a special character like '#' or '!' that will trigger a condition to exit the loop. I would see this like an exit/escape character. In the end is up to you, if you want you can do anything and what I'm proposing is just an idea to inspire you. For example another idea would be, if you'd like to go deeper, wait for another input to define what action to perform, you trigger the "command console" with '!' and then type 'q' to exit or also read the characters into a string at first so you could do complex "commands" like "!q".
Here's the simple version:
bool loop_condition = true;
do
{
if(input == '!')
{
loop_condition = false;
}
else
{
//Stuff you'd like to do if the read character is not !
}while(loop_condition == true);
Just to provide context here is what's happening:
I declare a variable named loop_condition
Inside the loop I check if the typed character is !
If so set the variable loop_condition to false with subsequent exit from the loop
Else just execute your code and loop
As I already said this is a very simple example just to give you an idea and can be improved a lot.
I suggest wrapping the for (counter=0... loop with a while (!cin.eof()) { block. This will allow the user to continue to enter in characters, until an EOF character (e.g. ctrl-D).
You may find you want to output a newline after every 7th character, to make the display look nice.
do {
//your code here;
} while (1);
This will repeatly infinitely which is not a good practice.
int number_of_phones = 10; // total number of phones you want
int i = 0;
do {
//your code here;
i=i+1;
} while (i<number_of_phones);
This will make it run 10 times for example
You can have whatever condition you want in a for loop, including nothing at all, which is treated as true.
for(;;) {
// code
}
is the same as
while (true) {
// code
}
is the same as
do {
// code
} while (true)
It sounds like you mixed up the placement of braces when you tried do { ... } while (true). You may want to move your big switch into a function, so that it's more obvious what scope a partiular } ends.
#include <iostream>
int phone_key(char key)
{
switch (key)
{
case 'A':
case 'a':
case 'B':
case 'b':
case 'C':
case 'c':
return 2;
case 'D':
case 'd':
case 'E':
case 'e':
case 'F':
case 'f':
return 3;
case 'G':
case 'g':
case 'H':
case 'h':
case 'I':
case 'i':
return 4;
case 'J':
case 'j':
case 'K':
case 'k':
case 'L':
case 'l':
return 5;
case 'M':
case 'm':
case 'N':
case 'n':
case 'O':
case 'o':
return 6;
case 'P':
case 'p':
case 'Q':
case 'q':
case 'R':
case 'r':
case 'S':
case 's':
return 7;
case 'T':
case 't':
case 'U':
case 'u':
case 'V':
case 'v':
return 8;
case 'W':
case 'w':
case 'X':
case 'x':
case 'Y':
case 'y':
case 'Z':
case 'z':
return 9;
}
return 0;
}
int main() {
for (;;)
{
std::cout << "\nEnter a phone number in letters only." << std::endl;
for (int counter = 0; counter < 7; counter++)
{
char phoneNumber;
cin >> phoneNumber;
if (counter == 3)
std::cout << "-";
std::cout << phone_key(phoneNumber);
}
}
}
I'm currently stuck on having to write a simulator for a real, old calculator (like those one dollar calculators, the ones with the buttons, in which you must enter your numbers one push-of-a-button at a time, can't write the Whole number directly and for now it is only in integers). I know for sure that there has to be a switch case for the 0-9 and one for the operators (including '='). Should break the cycle and print the result of the calculation, but I can use as many operators as I want in the each "session" (ex: 123+7-89/6*8+3). I am finding trouble in connecting the two loops and in printing the result. Thank you so much in advance.
#include <iostream>
using namespace std;
int execute(int n1, int n2, char c);
int main()
{
int acc, num=0;
char c, op;
cin>>c;
while (1) {
switch (c) {
case '0': cout << "0";
case '1': cout << "1";
case '2': cout << "2";
case '3': cout << "3";
case '4': cout << "4";
case '5': cout << "5";
case '6': cout << "6";
case '7': cout << "7";
case '8': cout << "8";
case '9': cout << "9";
num=num*10+static_cast<int>(c-'0');
acc=num;
op=c;
acc= execute(acc, num, op);
}
}
return 0;
}
int execute(int n1, int n2, char c) {
do {
switch (c) {
case '+': return (n1+n2);
case '-': return (n1-n2);
case '*': return (n1*n2);
case '/': return (n1/n2);
case '=': return true;
}
} while (!'=')
}
The ConvertHexToBinary function returns the proper binary string....followed by a bunch extra 0 & 1s
Cant figure out why the extra is being tacked on.
#include<iostream>
#include<vector>
#include<string>
#include<sstream>
using namespace std;
string ConvertHexToBinary(string str) {
string ToReturn;
for (int i = 2; i < str.size(); i++) {
switch (str[i]) {
case '0':
ToReturn.append("0000");
case '1':
ToReturn.append("0001");
case '2':
ToReturn.append("0010");
case '3':
ToReturn.append("0011");
case '4':
ToReturn.append("0100");
case '5':
ToReturn.append("0101");
case '6':
ToReturn.append("0110");
case '7':
ToReturn.append("0111");
case '8':
ToReturn.append("1000");
case '9':
ToReturn.append("1001");
case 'A':
ToReturn.append("1010");
case 'B':
ToReturn.append("1011");
case 'C':
ToReturn.append("1100");
case 'D':
ToReturn.append("1101");
case 'E':
ToReturn.append("1110");
case 'F':
ToReturn.append("1111");
}
}
return ToReturn;
}
int main()
{
int x = 25;
int *p = &x;
cout << p << endl;
std::ostringstream str;
str << p;
std::cout << str.str() << endl;
cout << ConvertHexToBinary(str.str()) << endl;
}