View previous topic :: View next topic |
Author |
Message |
rwskinner
Joined: 08 Dec 2006 Posts: 125 Location: Texas
|
Converting Ascii to Numeric |
Posted: Thu Jul 01, 2010 3:15 pm |
|
|
I haven't had to do any string conversions and I'm not getting the desired results. I know there has to be an easier way.
I have a buffer that contains GPS UTC Time such as
hhmmmss.sss = 053740.000
I'm trying to break the hours, minutes, and whole seconds out of this.
char TmpBuffer[40];
TmpBuffer contains '053740.000'
Code: |
int8 Hrs, Min, Sec;
char Hours[2];
char Minutes[2];
char Seconds[2];
strncpy(Hours,TmpBuffer,2);
strncpy(Minutes,TmpBuffer[2],2);
strncpy(Seconds,TmpBuffer[4],2);
Hrs = atoi(Hours); //Correct results
Min = atoi(Minutes); // Always zero
Sec = atoi(Seconds); //Always zero
|
Sorry, I'm a pascal guy and I know I'm missing something stupid.
Richard |
|
|
rwskinner
Joined: 08 Dec 2006 Posts: 125 Location: Texas
|
Re: Converting Ascii to Numeric |
Posted: Thu Jul 01, 2010 3:20 pm |
|
|
I see I had to do this to get it to work, but there should be an easier way right?
strncpy(Minutes,&TmpBuffer[2],2);
strncpy(Seconds,&TmpBuffer[4],2); |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu Jul 01, 2010 3:38 pm |
|
|
If you have to convert a single ASCII character to decimal, the following trick can be used: Code: | int8 Value;
char Ascii = '5';
Value = Ascii - '0';
// now Value == 5 |
Extending this to process your string, you can do: Code: | #define AtoI(x) (x - '0')
int8 Hrs, Min, Sec;
Hrs = (AtoI(TmpBuffer[0]) * 10) + AtoI(TmpBuffer[1]);
Min = (AtoI(TmpBuffer[2]) * 10) + AtoI(TmpBuffer[3]);
Sec = (AtoI(TmpBuffer[4]) * 10) + AtoI(TmpBuffer[5]); |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jul 01, 2010 3:50 pm |
|
|
rwskinner wrote: |
I have a buffer that contains GPS UTC Time such as
hhmmmss.sss = 053740.000
char Hours[2];
char Minutes[2];
char Seconds[2];
|
You're copying two ASCII bytes with strncpy() into each of these arrays.
Then you run atoi() on each array. But atoi() requires a null terminated
string. You don't have that.
strncpy() doesn't add a 0x00 byte at the end, and you don't have space
allocated for it in your arrays. So you need to do two things. Increase
the array sizes to 3, and manually write a 0x00 byte at the end of the
array after doing the strncpy(). |
|
|
rwskinner
Joined: 08 Dec 2006 Posts: 125 Location: Texas
|
|
Posted: Tue Jul 06, 2010 6:08 am |
|
|
Thanks PCM. I had previously tried that but I wasn't dereferencing the pointer, which for some reason when using arrays in C I thought you didn't have to, but I guess when you select a certain index you do have to which makes sense. I did modify it the way it should be.
ckielstra,
I see exactly what your doing and that is almost what I used to do in pascal by subtracting 48 from it, or even cooler, subtracting '0'. I tried it real quick but I some pretty weird results and at the end of the day I really did not dig in to it to find out why. For Example, seconds would only increment by 10 instead of 1. I'll take a quick look this morning to see why it was acting weird. |
|
|
collink
Joined: 08 Jan 2010 Posts: 137 Location: Michigan
|
|
Posted: Tue Jul 06, 2010 8:27 am |
|
|
rwskinner wrote: | Thanks PCM. I had previously tried that but I wasn't dereferencing the pointer, which for some reason when using arrays in C I thought you didn't have to, but I guess when you select a certain index you do have to which makes sense. I did modify it the way it should be.
|
Yes, this can trip people up. I'm reasonably sure that a lot of desktop compilers will allow one to use the array syntax without a deference operator and still get the proper result. However, CCS C will not try to guess what you want to do.
Another way to do it is to use the reference operator like this:
Code: |
Value = *(TmpBuffer + 4);
|
Whether or not you find that syntax more clear is up for interpretation. In some circumstances I find this alternate syntax more clear. |
|
|
|