0

I'm trying to parse the latitude,longitude values from a GPS NMEA Packet. I receive the packet as a char array. I parsed the latitude array and now i need to do a multiplication operation on it. But it is a char array. For example, here is an example array:

char *latitude;

latitude[0] = '4';
latitude[1] = '0';
latitude[2] = '5';

I want to multiply this values by 2. It must output 8,0,10 respectively. So i need to get the 4,2,6 values as integer. But if i use this arrays content as integer, it naturally outputs 52,48,53. I dont want to get the integer value which corresponds these ascii characters, i want to get the actual value as i see.

abdullah cinar
  • 543
  • 1
  • 6
  • 20

3 Answers3

2

First, you should specify exactly the input perhaps using EBNF notation and decide what the program should do on errors. A single example is never enough! See this

To convert the single character '4' to the integer 4, you could use ('4' - '0') (since the difference of chars is promoted to int), so I guess you want something like (latitude[0] - '0')*2 which you might print with printf("%d",(latitude[0] - '0')*2)

BTW, if your strings of digits contain one or several digits, you could use strtol to convert them to some long (e.g. "123 " converted to 123L) , and get the ending character (hence being able to detect and handle errors).

And you could also use sscanf; notice that it returns the number of scanned items (which you should always test) and what %d, %1d and %n means in the format string.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • As is `my_char1 - my_char2`, due to integer promotion. – Lundin Jan 11 '16 at 08:34
  • @V.Kravchenko I think he was commenting on how to get `4` out of `'4'` and not 52 ;) – Magisch Jan 11 '16 at 08:42
  • @Magisch: no, I didn't tell in my initial answer that the difference of two `char`s is an `int` – Basile Starynkevitch Jan 11 '16 at 08:43
  • The original comment was probably concerned about character literals like `'4'` already being of type `int` in C. Unlike C++ where they are of type `char`. Integer promotion only applies when you have character variables of type `char`, which is why I posted the comment above. – Lundin Jan 11 '16 at 08:54
2

Try to convert char to int via subtracting '0' from it. Example:

int doubledLatitude[3];
for (size_t i = 0; i < 3; ++i)
    doubledLatitude[i] = (latitude[i] - '0') * 2;
V. Kravchenko
  • 1,859
  • 10
  • 12
  • This is weird. I had tried to subtract '0' but couldn't succeed. I realized that if i define my array like this: char *latitude; It does not work. But if i define it like this: char latitude[3]; It is working. Do you have any idea why? – abdullah cinar Jan 11 '16 at 08:32
  • @abdullahcinar http://stackoverflow.com/questions/1704407/what-is-the-difference-between-char-s-and-char-s-in-c – Magisch Jan 11 '16 at 08:45
  • @abdullahcinar If you go like `char *latitude; latitude[0] = '4'; latitude[1] = '0'; latitude[2] = '5';` then you get access violation while writing to bad memory location, as code above lacks memory allocation. It is a completely different question, though. – V. Kravchenko Jan 11 '16 at 09:10
  • @V.Kravchenko I had used the first definition because i didn't know what will be the size of latitude array. But i better define it with a high enough size. Thanks for the answer,i got clarified. – abdullah cinar Jan 11 '16 at 09:15
2

First of all, you have to ensure the numbers are either single digit or you have handling in place. Please do note that chars can be used as integers without explicit conversion, due to integer promotion. For instance, if

latitude[0] = '1';
latitude[1] = '3';
latitude[2] = '9';

You have to pass these seperately and then cat them together. You can get the int value of a char by subtracting '0' since all single digit int values in ascii are sequential to each other. For this, write a function like this:

int asciiToInt (char ascii) {
if ( ascii < '0' || ascii > '9' ) {
return -1; //error
}
else
{
return (int)(ascii - '0'); // This works because '0' has the int value 48 in Ascii and '1' 49 and so on.
}
}

Then call it like this

int a = asciiToInt(latitude[0])*2;

Or, if you want to have a 3 digit number

int a;
a = asciiToInt(latitude[0]);
a += asciiToInt(latitude[1])*10;
a += asciiToInt(latitude[2])*100;
a = a*2;
Lundin
  • 195,001
  • 40
  • 254
  • 396
Magisch
  • 7,312
  • 9
  • 36
  • 52
  • This is totally working too. But do you have any idea about what is the difference between defining the array like char *latitude or char latitude[3]?First definition is not working or is not printing it properly. – abdullah cinar Jan 11 '16 at 08:44
  • @abdullahcinar http://stackoverflow.com/questions/1704407/what-is-the-difference-between-char-s-and-char-s-in-c – Magisch Jan 11 '16 at 08:45
  • 1
    `return (int)(ascii - '0');` The cast, as well as the parenthesis are superfluous clutter. `return ascii - '0';` is more readable and does the very same thing. If the reason behind the cast was to avoid implicit type promotions, you should have written `return (int)ascii - '0';`. – Lundin Jan 11 '16 at 09:00
  • @Lundin If you want, you can edit it to that. Personally, I find it fine this way. – Magisch Jan 11 '16 at 09:02
  • 2
    `'0' > ascii > '9'` ?? – BLUEPIXY Jan 11 '16 at 09:04
  • @BLUEPIXY He wants to convert numbers in char form to the int numbers. The function I wrote only gets desired output if the inputted char is a number. '0' is equal to 48, and '9' to 57. So the function only does what its intended to to if the int value of the inputted char is between 48 and 57, or '0' and '9' – Magisch Jan 11 '16 at 09:09
  • @BLUEPIXY Why is it bullshit? It treats the chars as int values. Please explain why you think this wont work. – Magisch Jan 11 '16 at 09:16
  • 1
    '0' > '1' > '9' --> 0 > '9' --> false, '0' > '\0' > '9' --> 1 > '9' --> false. this is always false. – BLUEPIXY Jan 11 '16 at 09:20
  • @Magisch Well it will work... but it suggests that the programmer 1) is unaware of the implicit promotion rules in C, and 2) that the programmer is unaware of the type of character literals in C. While the code itself isn't problematic, it is a typical case of "warning signs" to other programmers reading the code. If I found code like this upon code review, I would read all other code by that programmer much more carefully. In general, `return (something)` rather than `return something` is another such a warning sign. – Lundin Jan 11 '16 at 09:21
  • And there we have it, upon reading the code more carefully, BLUEPIXY just spotted a major beginner bug on the first line... The mentioned warning signs are almost always correct. – Lundin Jan 11 '16 at 09:23
  • @Lundin I assume the OP is not aware of that. I know you don't have to do it. But if you post it like you suggested, OP would have to be aware of implicit promotion and literals, and, if he was, he wouldn't be asking this question. And yes, as you can probably guess, im an Apprentice and started learning C myself about 3 months ago. – Magisch Jan 11 '16 at 09:23
  • @BLUEPIXY I see that now. I fixed that. Sorry about that. And it turns out I made another mistake trying to fix the first. Lundin fixed it now though, sorry about that. – Magisch Jan 11 '16 at 09:24