convert number with decimal places from char to int in c++ - c++

I was playing around with VS 2012 and came across a very tricky problem (for me at least). I have a simple program that does mathematical operations on inputs from the command line. However, if you input arguments with decimal places somewhere in the program it seems to forget the numbers after the decimal place.
double add (char const *inp, char const *inp2) { //addition function
double val = std::strtol(inp, NULL, 0);
double val2 = std::strtol(inp2, NULL, 0);
return val + val2;
}
and then calling the function :
double result = add(argv[1], argv[2]);
printf("%f \n", result);
and call from command line
test 52.2 44.6
returns 96 instead of 96.8.

You want strtod, not strtol. strtol only parses integers.
strtod only takes two arguments, because floating point numbers are always in base 10 (as far as strtod is concerned, anyway.)

I think you are turning your strings into longs (I'm guessing that's what strtol() is...). I was building a calculator and I had that problem - I wrote a function to handel it:
double string_to_double(string str)
{
int length = (int)str.length();
double output = 0; //This holds value of output. Will be added for each 10's digit
int decimalPos = length - 1;
for (int i = 0; i < length; i++)
{
if(str.at(i) == '.') // Find if there is a decimal point
{
decimalPos = i - 1; //Sets Decimal Position
str.erase(str.begin()+i);
length--;
}
}
for (int i = 0; i < length; i++)
{
switch (str.at(i))
{
case '1':
output += 1*pow(10, decimalPos - i);
break;
case '2':
output += 2*pow(10, decimalPos - i);
break;
case '3':
output += 3*pow(10, decimalPos - i);
break;
case '4':
output += 4*pow(10, decimalPos - i);
break;
case '5':
output += 5*pow(10, decimalPos - i);
break;
case '6':
output += 6*pow(10, decimalPos - i);
break;
case '7':
output += 7*pow(10, decimalPos - i);
break;
case '8':
output += 8*pow(10, decimalPos - i);
break;
case '9':
output += 9*pow(10, decimalPos - i);
break;
case '0':
break;
}
}
return output;
}
...but there is probably a better way

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 char into int in a function?

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';
}

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;
}
}

c++ Roman Additive Form Conversion

I'm working in a program that converts from Roman to Decimal. I have to validate 2 things: One that the characters entered are M or D or C or L or X or V or I, in other words valid for processing.
Number two, I have to make sure that bigger characters value go first and if not to print and error message and have the user to try again (this is the part where I am stuck)
For instance, If I wanted to input 9 and I input IX it should display an error message because is not in Additive form. It should be VIIII. How can I code this so it compares characters to know whether bigger letter values are first and so on?
I keep getting incorrect validation.
Is there a way to assign a value to the letters in the string? I'm thinking in comparing them as int values which I know how to and from there validate input format.
void RomanNum::setRomanNumber() //get input and calculate decimal equivalent
{
//I 1, V 5, X 10, L 50, C 100, D 500, M 1000
int value = 0;
string input;
char current, next;
enum validationData { M, D, C, L, X, V, I };
bool validationCharacters = true;
//bool validationAdditiveForm = true;
getline(cin, input, '\n');
for (int i = 0; i < input.length(); i++) //calculate each Roman letter at a time
{
current = input[i];
next = current + 1;
if (current >= validationData(next))
{
switch (input[i])
{
case 'M':
value += 1000;
break;
case 'D':
value += 500;
break;
case 'C':
value += 100;
break;
case 'L':
value += 50;
break;
case 'X':
value += 10;
break;
case 'V':
value += 5;
break;
case 'I':
value += 1;
break;
default:
validationCharacters = false;
break;
}
}
else
{
cout << "\nInvalid order. Bigger values go first\n";
}
}
}
I would recommend a std::map<char, int> to hold the mapping between letetrs and values.
With the map, you can then convert the input string (a sequence of characters) to a sequence of values (std::vector<int>). From there on, it's just a single check to see if the vector is sorted, and a single function call to add up all values. (I'll leave finding the right function as homework)

Write multiple things in a switch statement in C

So i need to have my switch statement go through and write out five two if the user says 52 but i cannot get it pass my 0-9. if they type 0-9 it works perfect but if i try to do any number past that it makes a blank. help!
#include <stdio.h>
int main (void)
{
int x;
printf("Please enter an integer: ");
scanf("%d", &x);
printf("\nYou have entered:\n\n");
for(x;x<0;x++);
switch (x)
{
case 0:
printf("zero");
break;
case 1:
printf("one");
break;
case 2:
printf("two");
break;
case 3:
printf("three");
break;
case 4:
printf("four");
break;
case 5:
printf("five");
break;
case 6:
printf("six");
break;
case 7:
printf("seven");
break;
case 8:
printf("eight");
break;
case 9:
printf("nine");
break;
}
printf("\n\n");
return 0;
}
do {
switch (x%10) {
...
}
x = x / 10;
} while (x>0) ;
or to get it in the right order use recursion
void f(int x) {
if (x==0) return;
f(x/10);
switch(x%10) { ... }
}
This question has been asked-and-answered before.
The for-loop you wrote is empty, because the body of the loop ends with the semi-colon:
for(x;x<0;x++) /* Empty Body!!*/ ;
The way a typical for loop works is:
for( /*Initialize*/; /*Test*/; /*Change*/)
{
/* Body */
}
In your case, I think you want:
for(int i=0; i < x; ++i)
{
switch(x)
{
[...]
}
}
This will:
Initialize i to 0
Test if i is LESS THAN x (the number you entered)
Keep increasing i by 1, until it gets up to x.
I'm not going to do your homework for you but consider the following pseudo-code:
print_text_digits(x)
{
if (x >= 10) print_text_digits(x / 10);
switch (x) {
print "zero" through "nine" as appropriate
}
}
main()
{
scan number into x;
print_text_digits(x);
}
This relies on a recursive routine so that you get your digits processed one at a time, with the might significant digit printed first.
You could solve this with recursion.
void printDigit(int x) {
int digit = x%10;
if(digit!=x)
printDigit(x/10);
switch(digit) {
...
}
}
This will print the most significant figure first, unlike the while loops most people are mentioning.
I believe you need this:
#include <stdio.h>
int main (void)
{
int count = 0;
int x, count2;
printf("Please enter an integer: ");
scanf("%d", &x);
printf("\nYou have entered:\n\n");
int aux = x;
while(aux>0) {
aux=aux/10;
count++;
}
count2 = count;
while(count) {
aux = x;
for(int i=count-1;i>0;i--)
aux=aux/10;
for(int i=count2-count;i>0;i--)
aux%=10;
switch (aux) {
case 0:
printf("zero");
break;
case 1:
printf("one");
break;
case 2:
printf("two");
break;
case 3:
printf("three");
break;
case 4:
printf("four");
break;
case 5:
printf("five");
break;
case 6:
printf("six");
break;
case 7:
printf("seven");
break;
case 8:
printf("eight");
break;
case 9:
printf("nine");
break;
}
count--;
if(count) printf(" ");
}
printf("\n\n");
return 0;
}
Now, with an input 52 it will propelly return five two.
#include <stdio.h>
static const char * const num[] = {
"zero ", "one ", "two " , "three ", "four ",
"five ", "six ", "seven ", "eight ", "nine "
};
void printNum(int x)
{
if (x < 10) {
printf(num[x]);
return;
}
printNum(x / 10);
printNum(x % 10);
}
int main (void)
{
int x;
printf("Please enter an integer: ");
scanf("%d", &x);
printf("\nYou have entered:\n\n");
printNum(x);
return 0;
}
Here's what you need to do. Similar to what #simonc said, it's a good idea to convert the user input to a string, then loop through the characters. For each character, convert it into an int and then take that into the switch statement.
EDIT---------------------------
Here's a way with strictly using integers.
First find how many digits your integer has. You can do this by a method mentioned here.
Then do integer division starting from the largest power of 10 that divides the integer you have and divide the divisor by 10 until you reach 1. For example:
If user input is 213, it has 3 digits. We divide this by 100 first.
213/100 = 2
We take the 2 and put it into the switch statement, outputting 2. Now we're done with the hundreds digit, so now we take the 13 from 213 and divide it by 10.
13/10 = 1 So now we output one.
Keep doing this process until you get to the ones digit.
Does this make sense?