How to convert char into int in a function? - c++

poziomy= char;
pionowy= digit; ( no problems with this one)
So I need to convert char into a digit in function but obviusly I cannot do char=int, so I dont know how to pass on the converted char into digit properly.
I guees i can do two functions but maybe there is an easier way?
I thought of making a new variable poziomy_c but I dont know how to pass it to Ruch_gracza()
int Convert_digit (int cyfra)
{
switch (cyfra)
{
case 10: return 0;break;
case 9: return 1;break;
case 8: return 2;break;
case 7: return 3;break;
case 6: return 4;break;
case 5: return 5;break;
case 4: return 6;break;
case 3: return 7;break;
case 2: return 8;break;
case 1: return 9;break;
}
}
int Convert_letter (char literka)
{
switch (literka)
{
case 'A': return 0; break;
case 'B': return 1; break;
case 'C': return 2; break;
case 'D': return 3; break;
case 'E': return 4; break;
case 'F': return 5; break;
case 'G': return 6; break;
case 'H': return 7; break;
case 'I': return 8; break;
case 'J': return 9; break;
}
}
void Conwert(int &pionowy, char poziomy)
{
pionowy=Convert_digit(pionowy);
int poziomy_c;
poziomy_c=Convert_letter (poziomy);
}
void Ruch_gracza1 (int plansza[10][10])
{
int pionowy ;
char poziomy;
cout << "wprowadz wspolrzedne pola na ktorym lezy pion który chcesz ruszyc ( w pionie , potem w poziomie)" << endl;
cin >> pionowy >> poziomy;
Conwert (pionowy,poziomy);
cout << pionowy << endl;
cout << poziomy << endl;
}

You can use char arithmetic to make this a whole lot easier. Since 'A' to 'Z' will be contiguous in ASCII/Unicode, you can do literka - 'A' to get how far literka is from A (which is what your switch is doing):
int Convert_letter (char literka) {
if(!std::isalpha(literka)) { return literka; } // Not a letter
return std::toupper(literka) - 'A';
}
Or if you want a more robust solution to cover even less common character encodings:
int Convert_letter (char literka) {
if(!std::isalpha(literka)) { return literka; } // Not a letter
std::string alphabet = "abcdefghijklmnopqrstuvwxyz";
return std::distance(std::begin(alphabet), std::find(std::begin(alphabet), std::end(alphabet), literka));;
}
Convert_digit will look similar (except with std::isdigit instead of std::isalpha).

You can do as
char c = 'B';
int digit = c - 'A';
return digit;

You need some knowledge about the ASCII table and data type in C++.
Simply, a char is an integer from -128 ... 127. If you declare a char variable name ch like this:
char ch = 'B';
C++ will understand that ch = 66 (look at ASCII table). So that we can do arithmetic operator with ch like an integer variable.
ch - 'A'; // result 1, because 'A' = 65
ch - 65; // same result with ch - 'A'
Finally, you can write your function like this:
int functionChar2Int(char x){
return x - 'A';
}

Related

Can anyone explain this function definition above the switch statement?

Here, I've made a function, that takes a character array and a single element array as input.
The input of expression is like "56+78", and then someone suggested this approach of using ascii code and for loops to store the two "numeric" substrings as two numbers, and used the character and switch statement below. But, I don't understand the part of storing these substrings as numbers and the asciicode concept.
void calculate(char ch[], char op[]){
int i;
int num1 = 0, num2 = 0;
for(i=0; ch[i]!='\0';i++)
{
if((int)ch[i]>=48 && (int)ch[i]<=57){
num1 = num1*10+(((int)ch[i])-48);
}
else{
op[0]=ch[i];
break;
}}
i++;
for(; ch[i]!='\0';i++)
{
if((int)ch[i] >= 48 && (int)ch[i] <= 57){
num2 = num2*10+(((int)ch[i])-48);
}
}
cout<<"OUTPUT: ";
switch(op[0])
{
case '+':
cout<<num1 + num2<<endl;
break;
case '-':
cout<<num1 - num2<<endl;
break;
case '*':
cout<<num1 * num2<<endl;
break;
case '/':
cout<<num1 / num2<<endl;
break;
}
}

How to convert a String to a char * in Arduino?

I'm doing a function to convert an integer into a hexadecimal char * in Arduino, but I came across the problem of not being able to convert a String to a char *. Maybe if there is a way to allocate memory dynamically for char * I do not need a class String.
char *ToCharHEX(int x)
{
String s;
int y = 0;
int z = 1;
do
{
if (x > 16)
{
y = (x - (x % 16)) / 16;
z = (x - (x % 16));
x = x - (x - (x % 16));
}
else
{
y = x;
}
switch (y)
{
case 0:
s += "0";
continue;
case 1:
s += "1";
continue;
case 2:
s += "2";
continue;
case 3:
s += "3";
continue;
case 4:
s += "4";
continue;
case 5:
s += "5";
continue;
case 6:
s += "6";
continue;
case 7:
s += "7";
continue;
case 8:
s += "8";
continue;
case 9:
s += "9";
continue;
case 10:
s += "A";
continue;
case 11:
s += "B";
continue;
case 12:
s += "C";
continue;
case 13:
s += "D";
continue;
case 14:
s += "E";
continue;
case 15:
s += "F";
continue;
}
}while (x > 16 || y * 16 == z);
char *c;
s.toCharArray(c, s.length());
Serial.print(c);
return c;
}
The toCharArray () function is not converting the string to a char array. Serial.print (c) is returning empty printing. I do not know what I can do.
Updated: Your Question re: String -> char* conversion:
String.toCharArray(char* buffer, int length) wants a character array buffer and the size of the buffer.
Specifically - your problems here are that:
char* c is a pointer that is never initialized.
length is supposed be be the size of the buffer. The string knows how long it is.
So, a better way to run this would be:
char c[20];
s.toCharArray(c, sizeof(c));
Alternatively, you could initialize c with malloc, but then you'd have to free it later. Using the stack for things like this saves you time and keeps things simple.
Reference: https://www.arduino.cc/en/Reference/StringToCharArray
The intent in your code:
This is basically a duplicate question of: https://stackoverflow.com/a/5703349/1068537
See Nathan's linked answer:
// using an int and a base (hexadecimal):
stringOne = String(45, HEX);
// prints "2d", which is the hexadecimal version of decimal 45:
Serial.println(stringOne);
Unless this code is needed for academic purposes, you should use the mechanisms provided by the standard libraries, and not reinvent the wheel.
String(int, HEX) returns the hex value of the integer you're looking to convert
Serial.print accepts String as an argument
char* string2char(String command){
if(command.length()!=0){
char *p = const_cast<char*>(command.c_str());
return p;
}
}

How to form an ASCII(Hex) number using 2 Chars?

I have char byte[0] = '1' (H'0x31)and byte[1] = 'C'(H'0x43)
I am using one more buffer to more buff char hex_buff[0] .i want to have hex content in this hex_buff[0] = 0x1C (i.e combination of byte[0] and byte[1])
I was using below code but i realized that my code is valid for the hex values 0-9 only
char s_nibble1 = (byte[0]<< 4)& 0xf0;
char s_nibble2 = byte[1]& 0x0f;
hex_buff[0] = s_nibble1 | s_nibble2;// here i want to have 0x1C instead of 0x13
What keeps you from using strtol()?
char bytes[] = "1C";
char buff[1];
buff[0] = strtol(bytes, NULL, 16); /* Sets buff[0] to 0x1c aka 28. */
To add this as per chux's comment: strtol() only operates on 0-terminated character arrays. Which does not necessarily needs to be the case for the OP's question.
A possible way to do it, without dependencies with other character manipulation functions:
char hex2byte(char *hs)
{
char b = 0;
char nibbles[2];
int i;
for (i = 0; i < 2; i++) {
if ((hs[i] >= '0') && (hs[i] <= '9'))
nibbles[i] = hs[i]-'0';
else if ((hs[i] >= 'A') && (hs[i] <= 'F'))
nibbles[i] = (hs[i]-'A')+10;
else if ((hs[i] >= 'a') && (hs[i] <= 'f'))
nibbles[i] = (hs[i]-'a')+10;
else
return 0;
}
b = (nibbles[0] << 4) | nibbles[1];
return b;
}
For example: hex2byte("a1") returns the byte 0xa1.
In your case, you should call the function as: hex_buff[0] = hex2byte(byte).
You are trying to get the nibble by masking out the bits of character code, rather than subtracting the actual value. This is not going to work, because the range is disconnected: there is a gap between [0..9] and [A-F] in the encoding, so masking is going to fail.
You can fix this by adding a small helper function, and using it twice in your code:
int hexDigit(char c) {
c = toupper(c); // Allow mixed-case letters
switch(c) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': return c-'0';
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F': return c-'A'+10;
default: // Report an error
}
return -1;
}
Now you can code your conversion like this:
int val = (hexDigit(byte[0]) << 4) | hexDigit(byte[1]);
It looks like you are trying to convert ASCII hex into internal representation.
There are many ways to do this, but the one I use most often for each nibble is:
int nibval(unsigned short x)
{
if (('0' <= x) && ('9' >= x))
{
return x - '0';
}
if (('a' <= x) && ('f' >= x))
{
return x - ('a' - 10);
}
if (('A' <= x) && ('F' >= x))
{
return x - ('A' - 10);
}
// Invalid input
return -1;
}
This uses an unsigned int parameter so that it will work for single byte characters as well as wchar_t characters.

can not convert parameter 1 from int into &int

Lets imagine I have got functions:
int switcherINT(char &c){
switch (c){
case '1': return 1; break;
case '2': return 2; break;
case '3': return 3; break;
case '4': return 4; break;
case '5': return 5; break;
case '6': return 6; break;
case '7': return 7; break;
case '8': return 8; break;
case '9': return 9; break;
case '0': return 0; break;
default: return err;
}
}
char switcherCHAR(int &c){
switch (c){
case 1: return '1'; break;
case 2: return '2'; break;
case 3: return '3'; break;
case 4: return '4'; break;
case 5: return '5'; break;
case 6: return '6'; break;
case 7: return '7'; break;
case 8: return '8'; break;
case 9: return '9'; break;
case 0: return '0'; break;
default: return errCH;
}
}
and I am trying to compute nest expression:
c.str[i] = switcherCHAR(switcherINT(pthis->str[pthis->size-i-1])-switcherINT(pb->str[pb->size-i-1])-loc);
where
longMath *pthis(this),*pb(&b);
longMath c;
class longMath{
protected:
char* str;
int size;
protected:
........
compiler says:
"can not convert parameter 1 from int into &int"
Haw can I solve this problem?
The expression that you've given as an argument to switcherCHAR gives you a temporary int. You cannot pass a temporary as a reference - unless you make the reference const. Just change switcherCHAR to take a const int& (and while you're at it, make switcherINT take a const char&). However, this are very simple types and you're probably better off just taking them by value. So change them to take just int and char.
Nonetheless, your functions are pretty strange. It is very easy to convert between a number x and it's char counterpart just by doing '0' + x. The numerical digit characters are guaranteed to be in consecutive order. So if you take the value of '0' and add, lets say, 5, you will get the value of the character '5'.
It would be much better to use functions like this:
int switcherINT(const char &c) {
return (c >= '0' && c <= '9') ? c - '0' : err;
}
char switcherCHAR(const int &c) {
return (c >= 0 && c <= 9) ? '0' + c : errCH;
}

int or char enum to int , not ASCII

I'm doing a poker game and have hit a wall. Any help would be great.
I have 12 card values. The values are chars either 2-9 or TJQKA (enumed below). I need to pass them to an int array such that their value is what gets passed (whether int value or enum value) instead of their ASCII.
for the example below, I want:
val[5] = {2,5,10,12,11}
instead of:
val[5] = {50,53,84,81,74}
enum cardvalues {T=10 , J , Q , K , A}
int val[5];
string value = "25TQJ";
for (int i = 0; i < 5; i++)
{
val[i] = value[i];
}
I would highly recommend using a map rather than an enum.
map<char,int> myCardMap;
myCardMap['T'] = 10;
...
val[i] = myCardMap[value[i]];
You'll need a conversion function:
int to_card(const char v)
{
switch(v)
{
case '2': return 2;
case '3': return 3:
// etc...
case 'T': return 10;
case 'J': return 11;
// etc...
}
Then in your loop:
val[i] = to_card(value[i]);
Make an std::map with ascii values in key and enum values in value
std::map<char, int> asciiMap;
asciiMap['T'] = 10;
asciiMap['J'] = 11;
//etc....
and then match the characters with the map
Generally you would need to convert the values from char to int. Here's the easiest way.
int convert_from_char(char c) {
if (c >= '2' && c <= '9') return (int)(c - '0');
else {
switch(c) {
case 'T': return (int)T;
case 'J': return (int)J;
case 'Q': return (int)Q;
case 'K': return (int)K;
case 'A': return (int)A;
default:
/* your program is borked. */
exit(1);
}
}
}
Then change your loop
for (int i = 0; i < 5; ++i)
val[i] = convert_from_char(value[i]);
I would suggest reconsidering using enums to represent cards, though. It will be easier in the long run just to make your own type, or use integers.
There is no way to directly convert from an enum symbol to the corresponding integer in C++ at runtime (obviously the compiler can do this at compile time). You may need to write a small helper function:
int card_value(char c) {
if (isdigit(c)) {
return c - '0';
} else {
switch (c) {
case 'T': return 10;
case 'J': return 11;
case 'Q': return 12;
case 'K': return 13;
case 'A': return 14;
default:
// whatever error handling here, such as:
return -1;
}
}
}
I suggest a switch:
switch (value[i]) {
case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
val[i] = atoi(value[i]);
break;
case 'T':
val[i] = 10;
break;
case 'J':
val[i] = 11;
break;
case 'Q':
val[i] = 12;
break;
case 'K':
val[i] = 13;
break;
case 'A':
val[i] = 14;
break;
default:
printf("Invalid character passed\n");
}
Create a function that will take a char argument (the ASCII card value, such as 'J') and return its numerical value. You might find the isdigit function and switch statement helpful.
If im understanding you correctly, you want to convert the string into card values (although for some reason you have the ace as 13 - id be tempted to say use 1 as the ace, although i can see you logic for it in a poker game).
Just using an enum wont help as at runtime you dont really have the information you need. An enum is a compile time concept mainly to assist the programmer and to handle checking.
There are many way to do what you want, you could have an array of index to char or a two entry array of char and value. For ease of alterations i would go with the following
typedef struct
{
char m_cCharacter;
int m_nValue;
} LOOKUP;
LOOKUP lookup_data[] = {
{ "2", 2 },
{ "3", 3 },
{ "4", 4 },
{ "5", 5 },
{ "6", 6 },
{ "7", 7 },
{ "8", 8 },
{ "9", 9 },
{ "T", 10 },
{ "J", 11 },
{ "Q", 12 },
{ "K", 13 },
{ "A", 14 }
};
int GetCharacter(char c)
{
int retval = -1; // Invalid
for(int i = 0; i < 13; i++)
{
if ( lookup_data[i].m_cCharacter == c )
{
retval = lookup_data[i].m_nValue;
break;
}
}
return retval;
}
for (int i = 0; i < 5; i++)
{
val[i] = GetCharacter(value[i]);
}
There are better ways with STL, and you should have more error checking and length of array detections, but hopefully you get the idea. You could use the enum in the lookup such as
{ "T", T },
If you preferred. Btw - i havent compiled this code so it probably wont build ;)
Try building a static array of size 256 such that the following gives the right answer:
for (int i = 0; i < 5; i++)
{
val[i] = AsciiToInt[value[i]];
}
That is,
AsciiToInt['2'] == 2
AsciiToint['T'] == 10,
AsciiToInt['J'] == 11
etc, but all invalid entries are zero.