I was writing some code, and came across some trouble. I wanted to write a function that checks if a string has any vowels, and tried to do it through a for loop with a switch statement inside. Apparently, it doesn't work and never returns true for some reason.
bool scanStr(string userInp) {
for (int i = 0; i < userInp.size(); i++) {
switch (userInp[i])
{
case 'a':
case 'A':
case 'e':
case 'E':
case 'i':
case 'I':
case 'o':
case 'O':
case 'u':
case 'U':
case 'y':
case 'Y':
return true;
break;
default:
return false;
}
}
}
I tried just testing if the program was actually iterating through the string, and it was, so I don't understand why in the function, it always returns false?
int main() {
string userInp;
string pigLatin;
cout << "Please enter a string to convert to pig Latin: " << endl;
cin >> userInp;
cout << endl;
// tests
for (int i = 0; i < userInp.size(); i++) { //checking if it actually iterates
cout << userInp[i];
}
cout << endl;
if (scanStr(userInp))
cout << "it has a vowel" << endl;
else
cout << "no vowel" << endl;
system("pause");
return 0;
}
At first I thought that it was because the loop kept on continuing even though there was a break statement after the last case, but I'm not entirely sure if that is the reason.
Any ideas?
I would suggest that you extract the logic of vowel testing into its own function:
bool is_vowel(char x)
{
switch (x)
{
case 'a':
case 'A':
case 'e':
case 'E':
case 'i':
case 'I':
case 'o':
case 'O':
case 'u':
case 'U':
case 'y':
case 'Y':
return true;
default:
return false;
}
}
Then you can use a standard algorithm instead of a loop:
#include <algorithm>
#include <string>
bool contains_vowel(const std::string& str)
{
return std::any_of(str.begin(), str.end(), is_vowel);
}
(I renamed scanStr to contains_vowel because that name is much more descriptive.)
Drop this lines from your function:
default:
return false;
They make your function return false on the first non-vowel it encounters.
You only want to return false if you reach the end of the loop and haven't returned true yet.
bool scanStr(string userInp)
{
for (int i = 0; i < userInp.size(); i++)
{
switch (userInp[i])
{
case 'a':
case 'A':
case 'e':
case 'E':
case 'i':
case 'I':
case 'o':
case 'O':
case 'u':
case 'U':
case 'y':
case 'Y':
return true;
}
}
return false;
}
A better approach in modern C++ would be:
bool scanStr(const std::string& userInp)
{
for (const auto c : userInp)
{
switch (c)
{
case 'a':
case 'A':
case 'e':
case 'E':
case 'i':
case 'I':
case 'o':
case 'O':
case 'u':
case 'U':
case 'y':
case 'Y':
return true;
}
}
return false;
}
But if you don't know what it means, don't worry about it now, your book or tutorial will explain soon enough.
Problem was, if any character wasn't vowel, that function imediatelly returned false. Also use const &. const allows you to pass const strings and reference saves some time, because C++ doesn't have to copy whole string.
bool scanStr(const string & userInp) {
for (int i = 0; i < userInp.size(); i++) {
switch (userInp[i])
{
case 'a':
case 'A':
case 'e':
case 'E':
case 'i':
case 'I':
case 'o':
case 'O':
case 'u':
case 'U':
case 'y':
case 'Y':
return true;
break;
}
}
return false;
}
First the compiler will turn the switch case into a lookup table, then auto will be decided as a data-type by the compiler based on the value assigned (in this case it's char).
Or just give it to your compiler, it knows how to do it.
bool scanStr(string userInp)
{
for(auto c : userInp)
{
switch (c)
{
case 'a': case 'A':
case 'e': case 'E':
case 'i': case 'I':
case 'o': case 'O':
case 'u': case 'U':
case 'y': case 'Y':
return true;
}
}
return false;
}
Related
My assignment for my class is to convert letters to numbers from an input file, like an old phone's keypad. i.e ABC are 2, DEF are 3, etc.
So, in the input file, one of the inputs is 1-800-ARID.
Using switch, I was able to successfully change the characters into numbers, but am unable to carry over the 1-800, or rather I'm not aware how to do so, or if it is even possible to carry over.
So far, I have this:
while(input.eof()){
input.get(ch);
switch (ch) {
case 'A': case 'B': case 'C': output << '2'; break;
case 'D': case 'E': case 'F': output << '3'; break;
case 'G': case 'H': case 'I': output << '4'; break;
case 'J': case 'K': case 'L': output << '5'; break;
case 'M': case 'N': case 'O': output << '6'; break;
case 'P': case 'Q': case 'R': case 'S': output << '7'; break;
case 'T': case 'U': case 'V': output << '8'; break;
case 'W': case 'X': case 'Y': case 'Z': output << '9'; break;
}
Running 1-800-ARID through this returns just 2743, without the prefix of 1-800.
You are outputting ONLY the characters you convert, nothing else. Simply add a default block to the switch to output all other characters as-is.
Also, your use of input.eof() is wrong.
Try this:
while (input.get(ch)){ // <— fixed
switch (ch) {
case 'A': case 'B': case 'C': output << '2'; break;
case 'D': case 'E': case 'F': output << '3'; break;
case 'G': case 'H': case 'I': output << '4'; break;
case 'J': case 'K': case 'L': output << '5'; break;
case 'M': case 'N': case 'O': output << '6'; break;
case 'P': case 'Q': case 'R': case 'S': output << '7'; break;
case 'T': case 'U': case 'V': output << '8'; break;
case 'W': case 'X': case 'Y': case 'Z': output << '9'; break;
default: output << ch; break; // <— add this
}
}
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 am having a problem with a test project in a visual studio.
From my understanding, the problem comes from the function 'yeet'.
The function does not finish the loop, since it does not print out "why!!" .
Could someone help me in identifying what is wrong with my code?
Here is my code
string reet(char reet) {
switch (reet) {
case 'a':
return "Zg";
break;
case'b':
return "dA";
break;
case 'c':
return "dG";
break;
case 'd':
return "aw";
break;
case 'e':
return "bw";
break;
case 'f':
return "dQ";
break;
case 'g':
return "cg";
break;
case 'h':
return "ZA";
break;
case 'i':
return "cQ";
break;
case 'j':
return "YQ";
break;
case 'k':
return "eA";
break;
case 'l':
return "dw";
break;
case 'm':
return "cw";
break;
case 'n':
return "ag";
break;
case 'o':
return "eQ";
break;
case 'p':
return "bA";
break;
case 'q':
return "aA";
break;
case 'r':
return "ZQ";
break;
case 's':
return "cA";
break;
case 't':
return "aw";
break;
case 'u':
return "eg";
break;
case 'v':
return "bg";
break;
case 'w':
return "aq";
break;
case 'x':
return "bQ";
break;
case 'y':
return "Yg";
break;
case 'z':
return "Zw";
break;
}
}
void yeet(string input) {
string yeet = input;
string bigBoi = "";
int yeetL = yeet.length() + 1;
for (int x = 0; x < yeetL;) {
bigBoi = bigBoi + reet(yeet[x]);
x++;
cout << bigBoi << endl;
}
cout << "why!" << endl;
}
int main() {
string input;
cin >> input;
yeet(input);
}
For further Information, I am Using C++ on Microsoft Visual Studio 2013.
I am trying to convert two (2) inputs from the user.
I am taking input in variable M. The K variable is unused.
I tried to solve it using for loop, but, I could not do it. The first loop could not stop.
Is it wrong to use an array?
And, can I use for loop after to input the binary output into a new array?
Here's my code:
include<iostream>
using namespace std;
int main()
{
char M[64],K[64];
long int i=0;
cout<<"Enter M: ";
cin>>M;
cout<<"M= ";
while(M[i])
{
switch(M[i])
{
case '0':
cout<<"0000";
break;
case '1':
cout<<"0001";
break;
case '2':
cout<<"0010";
break;
case '3':
cout<<"0011";
break;
case '4':
cout<<"0100";
break;
case '5':
cout<<"0101";
break;
case '6':
cout<<"0110";
break;
case '7':
cout<<"0111";
break;
case '8':
cout<<"1000";
break;
case '9':
cout<<"1001";
break;
case 'A':
cout<<"1010";
break;
case 'B':
cout<<"1011";
break;
case 'C':
cout<<"1100";
break;
case 'D':
cout<<"1101";
break;
case 'E':
cout<<"1110";
break;
case 'F':
cout<<"1111";
break;
case 'a':
cout<<"1010";
break;
case 'b':
cout<<"1011";
break;
case 'c':
cout<<"1100";
break;
case 'd':
cout<<"1101";
break;
case 'e':
cout<<"1110";
break;
case 'f':
cout<<"1111";
break;
default:
cout<<"nInvalid hexadecimal digit "<<M[i];
}
i++;
}
return 0;
cout<<"\nEnter K: ";
cin>>K;
cout<<"K: ";
while(K[i])
{
switch(K[i])
{
case '0':
cout<<"0000";
break;
case '1':
cout<<"0001";
break;
case '2':
cout<<"0010";
break;
case '3':
cout<<"0011";
break;
case '4':
cout<<"0100";
break;
case '5':
cout<<"0101";
break;
case '6':
cout<<"0110";
break;
case '7':
cout<<"0111";
break;
case '8':
cout<<"1000";
break;
case '9':
cout<<"1001";
break;
case 'A':
cout<<"1010";
break;
case 'B':
cout<<"1011";
break;
case 'C':
cout<<"1100";
break;
case 'D':
cout<<"1101";
break;
case 'E':
cout<<"1110";
break;
case 'F':
cout<<"1111";
break;
case 'a':
cout<<"1010";
break;
case 'b':
cout<<"1011";
break;
case 'c':
cout<<"1100";
break;
case 'd':
cout<<"1101";
break;
case 'e':
cout<<"1110";
break;
case 'f':
cout<<"1111";
break;
default:
cout<<"nInvalid hexadecimal digit "<<K[i];
}
i++;
}
return 0;
}
first of all, you are using 2 parts of the code, repetitively, you should consider using a function for higher scalability (Imagine if you wanted to convert 5 inputs, it is not a good practice to copypaste the switch 5 times.
Then, the for loop is mostly used for known sized collections, and the while for unknown sized ones, so for the for you can just put the size of your array:
for(int i = 0;i<64;i++){
convert(M[i]);
}
If you want to have a good scalability you should consider using sizeof(M)/sizeof char or things like a global constant or #define for the maximun string you can have...
Hope it helped.
Why does this code always return 'false' and activates the goto even when I type a digit? Can anyone please help me? Thank you!
char userValue = '4';
auto h = true;
tryAgain:
std::cout << "Please type a digit: ";
std::cin >> userValue;
switch (userValue) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
h = true;
default:
h = false;
}
switch (h) {
case true:
std::cout << "This character is a digit.";
case false:
std::cout << "Wrong! Try again!" << std::endl;
goto tryAgain;
}
You simply forgot to break out of the case if it has been processed.
That way it will fall through the cases and handle the false case after the true case has been handled.
switch (h) {
case true:
std::cout << "This character is a digit.";
break;
case false:
std::cout << "Wrong! Try again!" << std::endl;
goto tryAgain;
//not necessarily needed because goto leaves the scope anyway.
//break;
}
The same issue here, break if you wan't to stop the fallthrough:
switch (userValue) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
h = true;
break;
default:
h = false;
break;
}