Swtich case in strings - c++

I have an error while I compile my code.
Error Output:
main.cpp: 35:16: error: switch quantity not an integer
I dont know why. The code is as follows:
int Values(string letter) {
switch( tolower(letter) ) {
case 'a' : a.setTotal();
break;
Regards

A string is not a char, it's an object representing an array of chars.
Instead of passing in a string to that function, you should pass in a char.
tolower(int) exists in C++ and it was meant to take characters, not strings.
Here's another way to fix this that needs less changes to your code:
Since I'm pretty sure that letter is going to be a string of length 1 judging by the name, you can change your switch statement to access letter[0], which will be the first character in the string. You would also have to pass letter[0] to tolower.

letter is string, so tolower(letter) produce a string. But your case is character ('a'). Additionally it is impossible in C/C++ to use switch for string.
user this line instead:
switch( tolower(letter.data[0]) )

The switch inscrutvion takes only enumerated types(enum), chars(char) or integers (int, unsigned, long)

It looks like you want to work with a single character.
Change your function's parameter:
int Values(string letter)
to this:
int Values(char letter)
And the switch statement will work.

Related

C++ Atoi can't handle special characters

Im using this atoi to remove all letters from the string. But my string uses special characters as seen below, because of this my atoi exits with an error. What should I do to solve this?
#include <iostream>
#include <string>
using namespace std;
int main() {
std::string playerPickS = "Klöver 12"; // string with special characters
size_t i = 0;
for (; i < playerPickS.length(); i++) { if (isdigit(playerPickS[i])) break; }
playerPickS = playerPickS.substr(i, playerPickS.length() - i); // convert the remaining text to an integer
cout << atoi(playerPickS.c_str());
}
This is what I believe is the error. I only get this when using those special characters, thats why I think thats my problem.
char can be signed or unsigned, but isidigt without a locale overload expects a positive number (or EOF==-1). In your encoding 'ö' has a negative value. You can cast it to unsigned char first: is_digit(static_cast<unsigned char>(playerPickS[i])) or use the locale-aware variant.
atoi stops scanning when it finds something that's not a digit (roughly speaking). So, to get it to do what you want, you have to feed it something that at least starts with the string you want to convert.
From the documentation:
[atoi] Discards any whitespace characters until the first non-whitespace character is found, then takes as many characters as possible to form a valid integer number representation and converts them to an integer value. The valid integer value consists of the following parts:
(optional) plus or minus sign
numeric digits
So, now you know how atoi works, you can pre-process your string appropriately before passing it in. Good luck!
Edit: If your call to isdigit is failing to yield the desired result, the clue lies here:
The behavior is undefined if the value of ch is not representable as unsigned char and is not equal to EOF.
So you need to check for that yourself before you call it. Casting playerPickS[i] to an unsigned int will probably work.

How to use Char in Switch Case

How to make this work
#include <stdio.h>
#include <conio.h>
main()
{
char C;
printf("R=This Program gives you some of the information of the country you entered.");
printf("Enter a Country:");
scanf("%c", &C);
switch(C)
{
case 'Algeria':
printf("Capital: Algiers");
printf("Currency and Country Code: Algerian Dinar (DZD)");
break;
}
getch ();
return 0;
}
The Error is
11 8 C:\Users\Edrian\Desktop\C++ Codes\World Information.cpp [Warning] character constant too long for its type
C:\Users\Edrian\Desktop\C++ Codes\World Information.cpp In function 'int main()':
11 8 C:\Users\Edrian\Desktop\C++ Codes\World Information.cpp [Warning] case label value exceeds maximum value for
type
Char contains only one character if you want to use more than one character you have to use string data type.In your case you should use string
11 8 C:\Users\Edrian\Desktop\C++ Codes\World Information.cpp [Warning] character constant too long for its type
This says that 'Algeria' is too long for the type char, which should be a single letter, e.g. 'A' (as suggested here).
char string[256];
scanf("%255s", string);
switch (s[0]) {
case 'A':
if (0 == strcmp(string, "Algeria")) {
This should work. You may need to #include <string.h> for strcmp.
Notice how "Algeria" is now double-quoted, while 'A' is single-quoted.
I elided out lines that would be the same in both, mostly printf statements. Make sure that you get the curly braces right. I added a { for the if. You'll need to add a } to match (before the break;).
You could also say
if (!strcmp(string, "Algeria")) {
But I thought that it might be easier for you to read the other way. Functionally the two statements are the same, as C considers zero to be falsey.
See also:
Read no more than size of string with scanf()
What's the difference between these 4 items: character, array, string, literal in C?
Does the C standard explicitly indicate truth value as 0 or 1?
Why the switch statement cannot be applied on strings? (kudos to Yksisarvinen for finding)
Know the difference :
'Algeria' this is a string literal so it should be "Algeria" and your C should be a string
'A' is a character

Switch statement on char variable

A library we are using defines constants and we have:
const char field[] = "666"
and I would like to:
switch(an_int){
case field:
Is there a way to achieve this? I get a compiler error saying field is not usable in a constant expression (GCC 5.2).
I would really wish to avoid modifying the declaration of field if possible.
field is an array. It is not a single value you can switch on.
You're trying to switch on the contents of a character array, when it is interpreted as an integer value.
Use atoi(), or a helper std::istringstream's operator >>, to convert the array into an int variable, then switch on it.
No, It is not possible to have switch statement on char array/string. In case you are sure that the field will contain numeric value then convert char array to integer.

isdigit() not recognising "1" as a numeric value

I am parsing a string, validating whether a number inside the string is an int.
std::string segmentS
if(!isdigit(std::stoi(segmentS))){
std::cout<<"Not a location +"<<segmentS<<std::endl;
//does something
break;
}
segmentS is the substring that is suppose to be the integer
Even when I ensure that segmentS is a number, !isdigit(std::stoi(segmentS)) still holds true. Even when segmentS is printed out after the not a location message, it is 1 which is a number, however it isn't being seen as a number, when it runs into this if statement.
std::stoi(segmentS) will convert segmentS to an int value, which is then passed into isdigit, except isdigit assumes the input is a character.
Remove the call to stoi.
isdigit takes a single char as an input, not an integer.

Convert a single character to lowercase in C++ - tolower is returning an integer

I'm trying to convert a string to lowercase, and am treating it as a char* and iterating through each index. The problem is that the tolower function I read about online is not actually converting a char to lowercase: it's taking char as input and returning an integer.
cout << tolower('T') << endl;
prints 116 to the console when it should be printing T.
Is there a better way for me to convert a string to lowercase?
I've looked around online, and most sources say to "use tolower and iterate through the char array", which doesn't seem to be working for me.
So my two questions are:
What am I doing wrong with the tolower function that's making it return 116 instead of 't' when I call tolower('T')
Are there better ways to convert a string to lowercase in C++ other than using tolower on each individual character?
That's because there are two different tolower functions. The one that you're using is this one, which returns an int. That's why it's printing 116. That's the ASCII value of 't'. If you want to print a char, you can just cast it back to a char.
Alternatively, you could use this one, which actually returns the type you would expect it to return:
std::cout << std::tolower('T', std::locale()); // prints t
In response to your second question:
Are there better ways to convert a string to lowercase in C++ other than using tolower on each individual character?
Nope.
116 is indeed the correct value, however this is simply an issue of how std::cout handles integers, use char(tolower(c)) to achieve your desired results
std::cout << char(tolower('T')); // print it like this
It's even weirder than that - it takes an int and returns an int. See http://en.cppreference.com/w/cpp/string/byte/tolower.
You need to ensure the value you pass it is representable as an unsigned char - no negative values allowed, even if char is signed.
So you might end up with something like this:
char c = static_cast<char>(tolower(static_cast<unsigned char>('T')));
Ugly isn't it? But in any case converting one character at a time is very limiting. Try converting 'ß' to upper case, for example.
To lower is int so it returns int. If you check #include <ctype> you will see that definition is int tolower ( int c ); You can use loop to go trough string and to change every single char to lowe case. For example
while (str[i]) // going trough string
{
c=str[i]; // ging c value of current char in string
putchar (tolower(c)); // changing to lower case
i++; //incrementing
}
the documentation of int to_lower(int ch) mandates that ch must either be representable as an unsigned char or must be equal to EOF (which is usually -1, but don't rely on that).
It's not uncommon for character manipulation functions that have been inherited from the c standard library to work in terms of ints. There are two reasons for this:
In the early days of C, all arguments were promoted to int (function prototypes did not exist).
For consistency these functions need to handle the EOF case, which for obvious reasons cannot be a value representable by a char, since that would mean we'd have to lose one of the legitimate encodings for a character.
http://en.cppreference.com/w/cpp/string/byte/tolower
The answer is to cast the result to a char before printing.
e.g.:
std::cout << static_cast<char>(std::to_lower('A'));
Generally speaking to convert an uppercase character to a lowercase, you only need to add 32 to the uppercase character as this number is the ASCII code difference between lowercase and uppercase characters, e.g., 'a'-'A'=97-67=32.
char c = 'B';
c += 32; // c is now 'b'
printf("c=%c\n", c);
Another easy way would be to first map the uppercase character to an offset within the range of English alphabets 0-25 i.e. 'a' is index '0' and 'z' is index '25' inclusive and then remap it to a lowercase character.
char c = 'B';
c = c - 'A' + 'a'; // c is now 'b'
printf("c=%c\n", c);