How to limit char length - c++

I know people will immediately look at the title and just say: "Use String" or "Char can only be length of 1" but there are problems with those.
For the first, due to later on in the code using a switch statement my variable must stay as a char so that it does not cause any errors, and for the second answer during testing I found out that even if I entered a multi-length input it would just run each character into the switch statement separately which I do not want to happen. Any help is welcomed, oh and here's the code:
char input;
do {
cout << "Please enter a number from 1 to 4.";
cin >> input;
if (sizeof(input)!=1) {
cout << "Please just enter a number";
}
else {
switch (input) {
case '1': {
cout << "One";
break;
}
case '2': {
cout << "Two";
break;
}
case '3': {
cout << "Three";
break;
}
case '4': {
cout << "Four";
break;
}
default:
cout << "Enter only a number from 1-4!";
}
}
} while ((input) != '4');
Note that I have at least attempted to use strlen and the size functions but to no avail.

Well, use string, because char can only be length of 1.
std::string input;
std::cin >> input;
if (input.size() != 1) {
std::cout << "Wrong input";
} else {
switch (input.front()) {
case '1':
// ...
}
}

Related

Functions to check if the user's input is correct not working

I have created some C++ code that is supposed to check to see if a user's input is correct but it isn't quite working how I want it to. Whenever you type an integer first, and then a couple of characters after it, the terminal spams would you like to try again y/n a couple of times. I have tried to limit the amount of times it can output this, but nothing has worked.
#include <iostream>
#include <limits>
using namespace std;
int again()
{
char yorn = 'q';
cout << "\n Would you like to run this program again? y/n: ";
cin >> yorn;
if (cin.fail()) {
int dof1 = 1; // dof1 stands for don't overflow 1
for (int i = 0; i < dof1; i++) {
cout << "ERROR -- You did not enter a valid symbol";
// get rid of failure state
cin.clear();
// discard 'bad' character(s)
cin.ignore(numeric_limits<streamsize>::max(), '\n');
bool check = again();
if (check == true) {
check = false;
return again();
}
else
return 0;
}
}
switch (yorn) {
case 'y':
return true;
break;
case 'n':
return false;
break;
default:
return again();
break;
}
}
int main()
{
int choice = 0;
cout << "\nWelcome to the Weight Tracker! Type 000 at any time to exit\n"
<< "Choose the option you would like to use below \n"
<< "1) \n"
<< "2) \n"
<< "3) \n"
<< "Option selected: ";
cin >> choice;
if (cin.fail()) {
int dof2 = 1; // dof2 stands for don't overflow 2
for (int i = 0; i < dof2; i++) {
cout << "ERROR -- You did not enter an integer";
// get rid of failure state
cin.clear();
// discard 'bad' character(s)
cin.ignore(numeric_limits<streamsize>::max(), '\n');
bool check = again();
if (check == true) {
check = false;
return main();
}
else
return 0;
}
}
switch (choice) {
case 1:
cout << " use later";
break;
case 2:
cout << " use later";
break;
case 3:
cout << " use later";
break;
default:
cout << "ERROR -- Input invalid \n";
bool check = again();
if (check == true) {
check = false;
return main();
}
else
return 0;
break;
}
return 0;
}
You are missing one cin.ingnore
default:
cout << "ERROR -- Input invalid \n";
cin.ignore(numeric_limits<streamsize>::max(), '\n'); // ADD this line
bool check = again();
To be honest. This code is mess. Please remove recursion from it.

Reading digits and converting to words

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.

The case at line 42 keeps falling through to the case at line 49

Answer the first 3 questions with n-y-n. That last statement should have stopped but instead goes to the next question instead.
Please ignore the rest if you want. If there are any mistakes, please tell me.
I'm currently taking a programming class for the first time so be gentle with me
#include <iostream>
using namespace std;
int main()
{
//Tattoo Decision
char ans;
cout <<"This program will help you determine whether you should get a tattoo or not?";
cout <<"\nPlease answer the questions with either y (yes) or n (no)";
cout <<"\n\n\nAre you Drunk?: ";
cin >>ans;
switch (ans) //finished
{
case 'y':
{
cout <<"\n\nWell, for obvious reasons, Don't get a tattoo'";
break;
}
case 'n':
{
cout <<"\n\nAre your friends egging on you?: ";
cin>>ans;
switch(ans)//finished
{
case 'y':
{
cout <<"\n\nAre they laughing?: ";
cin >>ans;
switch(ans)//finished
{
case 'y':
{
cout<<"\n\nDon't get a tattoo";
break;
}
case'n':
{
cout<<"\n\nLaughing or not, Don't get a tattoo";
break;
}
}
}
case'n':
{
cout<<"\n\nDoes the tattoo have a special meaning to you?: ";
cin>>ans;
switch(ans)//finished
{
case'y':
{
cout<<"\n\nIs it a name?: ";
cin>>ans;
switch(ans)//unfinished
{
case'y':
{
cout<<"\n\nIs it your significant other?: ";
cin>>ans;
switch(ans)//unfinished
{
case'y':
{
cout<<"\n\nDon't fucking get that tattoo'";
break;
}
}
}
}
}
case'n':
{
cout<<"\n\nThen why are you getting a tattoo for? Don't get one";
break;
}
}
}
}
}
}
return 0;
}
Looks like you are missing a break, try adding as below:
int main()
{
//Tattoo Decision
char ans;
cout <<"This program will help you determine whether you should get a tattoo or not?";
cout <<"\nPlease answer the questions with either y (yes) or n (no)";
cout <<"\n\n\nAre you Drunk?: ";
cin >>ans;
switch (ans) //finished
{
case 'y':
{
cout <<"\n\nWell, for obvious reasons, Don't get a tattoo'";
break;
}
case 'n':
{
cout <<"\n\nAre your friends egging on you?: ";
cin>>ans;
switch(ans)//finished
{
case 'y':
{
cout <<"\n\nAre they laughing?: ";
cin >>ans;
switch(ans)//finished
{
case 'y':
{
cout<<"\n\nDon't get a tattoo";
break;
}
case'n':
{
cout<<"\n\nLaughing or not, Don't get a tattoo";
break;
}
}
break; // <---------- *****
}
case'n':
{
cout<<"\n\nDoes the tattoo have a special meaning to you?: ";
cin>>ans;
switch(ans)//finished
{
case'y':
{
cout<<"\n\nIs it a name?: ";
cin>>ans;
switch(ans)//unfinished
{
case'y':
{
cout<<"\n\nIs it your significant other?: ";
cin>>ans;
switch(ans)//unfinished
{
case'y':
{
cout<<"\n\nDon't get that tattoo'";
break;
}
}
}
}
break; //<--------- *****
}
case'n':
{
cout<<"\n\nThen why are you getting a tattoo for? Don't get one";
break;
}
}
}
}
}
}
return 0;
}

Pig Latin converter using toupper

I'm having trouble converting using toupper on the first character in my string.
I used tolower(first[0]) to turn the first letter into lower case.
Why doesn't toupper(first[0]) make the first character upper case?
Also, is there a way to move the first character in a string to the last spot?
Thanks a lot in advance.
#include <iostream>
#include <string>
using namespace std;
int main ()
{
char ans;
do{
string first, last;
char first_letter, first_letter2;
cout << "This program will convert your name "
<< "into pig latin.\n";
cout << "Enter your first name: \n";
cin >> first;
cout << "Enter your last name: \n";
cin >> last;
cout << "Your full name in pig latin is ";
for(int x = 0; x < first.length(); x++){
first[x] = tolower(first[x]);
}
for(int x = 0; x < last.length(); x++){
last[x] = tolower(last[x]);
}
first_letter = first[0];
bool identify;
switch (first_letter)
{
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
identify = true;
break;
default:
identify = false;
}
if(identify == true){
toupper(first[0]);
cout << first << "way" << " ";
}
first_letter2 = last[0];
bool identify2;
switch (first_letter2)
{
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
identify2 = true;
break;
default:
identify2 = false;
}
if(identify2 == true){
toupper(first[0]);
cout << last << "way" << endl;
}
cout << "You you like to try again? (Y/N)\n";
cin >> ans;
} while(ans == 'y' || ans == 'Y');
return 0;
}
Just a simple blunder, compare
first[x] = tolower(first[x]);
with
toupper(first[0]);
usual case of the 'can't see the obvious thing missing' syndrome... I hate those mistakes.
As for moving the first character to the end I'd usually just use substr() for a simple case:
str = str.substr(1) + str[0];

while loop - nothing happens after first input

int option;
int invalidOption2 = 0;
while(invalidOption2 == 0){
try{
cin>>option;
if(!cin){
error("invalid input");
}
if(option<1 || option>2){
error("invalid input");
}
if(option==1) {
invalidOption2 = 1;
cout<<"option 1 was selected"<<endl;
}
else if(option==2) {
invalidOption2 = 1;
cout<<"option 2 was selected"<<endl;
}
}
catch(runtime_error& e) {
cerr <<"Please enter a valid option" << endl;
}
}
When using the above code, for the first value I input it will move on to the next line and wait for another input, instead of displaying either the option messages or the error message. However when I enter a second value it works as normal.
for example if I entered
a (nothing happens here, so I need to enter another value)
1
"you have selected option 1"
would be displayed and no error message for the original invalid input.
I would like to know how to get the result below instead.
a
"Please select a valid option"
1
"you have selected option 1"
any help would be appreciated
You won't get to the "Please enter a valid option" unless an
exception is thrown. You don't show error, but if it doesn't
throw an exception, you'll never get to the catch block.
Also, cin >> option almost certainly leaves a new line in the
buffer, which may cause later problems, and whien you enter an
alpha, if option is type int, cin will enter an error
state, which needs to be cleared (and the erronous input
removed). So in the error case (!cin), you need to call
cin.clear(), and in all cases, you probably want to call
cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n'
).
An alternative solution, which avoids most of these problems, is
to read complete lines (using std::getline( std::cin, line )),
and then use std::istringstream to parse the line. This will
leave std::cin in a good state, and ready to input the next
line.
Option is likely of integer type, so cin can't read 'a' into it, so it is ignored.
Is this your case?
You could modify it like this:
char option;
while(invalidOption2 == 0){
try{
cin>>option;
if(!cin){
error("invalid input");
}
if(option<'1' || option>'2'){
error("invalid input");
}
if(option=='1') {
invalidOption2 = 1;
cout<<"option 1 was selected"<<endl;
}
else if(option=='2') {
invalidOption2 = 1;
cout<<"option 2 was selected"<<endl;
}
}
catch(runtime_error& e) {
cerr <<"Please enter a valid option" << endl;
}
}
This should work how you expect it to.
However, construction like this:
char option;
while (cin >> option) {
if ((option == '1') || (option == '2')) {
break;
}
else {
cout << "Please enter 1 or 2." << endl;
}
}
cout << "option " << option " << " was selected" << endl;
Is probably better ^_^
I think this looks a better code (at least for the eyes):
int option;
int invalidOption2 = 0;
while(invalidOption2 == 0)
{
try
{
cin>>option;
switch(option)
{
case 1 :
invalidOption2 = 1;
cout<<"option 1 was selected"<<endl;
break;
case 2 :
invalidOption2 = 1;
cout<<"option 2 was selected"<<endl;
break;
default :
error("invalid input");
}
catch(runtime_error& e)
{
cerr <<"Please enter a valid option" << endl;
}
}
If you still think you have problems with int and char with cin then better use :
option = getchar();
I think calling cin twice may be the issue here, but I'm not certain. Something like this should work well too:
char option[80]; // 80 is the standard terminal line length
bool loop = 1;
while(loop)
{
cin >> option;
if (option[1]=='\n') // testing if string is length 1
{
cout << "Please select a valid input\n";
continue; // if not, display error and try again
};
switch(option[0])
{
case '1': loop=0; break; // add whatever before break
case '2': loop=0; break;
default: cout << "please select a valid input\n"; break;
};
};
cout << "Option "<< option << "was selected\n";
I didn't compile this, but it should be okay.