EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

Printf 'long' format specifications

Started by lewis November 24, 2006
Hi,
My problem is pretty basic , still am stuck. I am trying to use
sprintf() to format a long value to the destination string.I tried
using %d , %l etc but dint get he expected results. I went thru th
ecrosstudio documentation for printf format specifications but ended
more confused dan before.
Please advice
Thanks in advance.
Regards,
Lewis

Beginning Microcontrollers with the MSP430

lewis wrote:
> Hi,
> My problem is pretty basic , still am stuck. I am trying to use
> sprintf() to format a long value to the destination string.I tried
> using %d , %l etc but dint get he expected results. I went thru th
> ecrosstudio documentation for printf format specifications but ended
> more confused dan before.

You want %ld for a long integer, %hd for a short one, and %d for the default.
Hi Clifford,
Thnx. I tried the following code
unsigned long samples[20];
long lTest ;
lTest = 1001;
i = sprintf(samples,"%ld",lTest);
I ran the code using teh simulator but i get an incorrect result in
the output buffer.

Regards,
Lewis

--- In m..., Clifford Heath wrote:
>
> lewis wrote:
> > Hi,
> > My problem is pretty basic , still am stuck. I am trying to use
> > sprintf() to format a long value to the destination string.I tried
> > using %d , %l etc but dint get he expected results. I went thru th
> > ecrosstudio documentation for printf format specifications but ended
> > more confused dan before.
>
> You want %ld for a long integer, %hd for a short one, and %d for the
default.
>
lewis wrote:
> I tried the following code
> unsigned long samples[20];
> long lTest ;
> lTest = 1001;
> i = sprintf(samples,"%ld",lTest);
> I ran the code using teh simulator but i get an incorrect result in
> the output buffer.

The output buffer should be char[20], not unsigned long[20].

I'm a bit alarmed that the compiler didn't prevent you from
compiling it - please read the manual and find out how to:
* require function prototypes
* issue all warnings
* #include the required files (stdio.h in this case)

Then, don't try to run code that compiles with warnings, and
you'll save yourself a lot of time.
Lewis,

Have you ensured that your project has formatting of longs enabled in your linker options ?
Else, because you use an ulong array, you will have 3 out of every 4 chars missing when you look
at it with the simulator, unless you put a watch or memory window on the _actual_ start address
of samples[].

Best Regards,
Kris

-----Original Message-----
From: m... [mailto:m...] On Behalf Of lewis
Sent: Saturday, 25 November 2006 3:25 PM
To: m...
Subject: [msp430] Re: Printf 'long' format specifications

Hi Clifford,
Thnx. I tried the following code
unsigned long samples[20];
long lTest ;
lTest = 1001;
i = sprintf(samples,"%ld",lTest);
I ran the code using teh simulator but i get an incorrect result in
the output buffer.

Regards,
Lewis

--- In m..., Clifford Heath wrote:
>
> lewis wrote:
> > Hi,
> > My problem is pretty basic , still am stuck. I am trying to use
> > sprintf() to format a long value to the destination string.I tried
> > using %d , %l etc but dint get he expected results. I went thru th
> > ecrosstudio documentation for printf format specifications but ended
> > more confused dan before.
>
> You want %ld for a long integer, %hd for a short one, and %d for the
default.
>

Yahoo! Groups Links
Why should the compiler alarm ?

I don't see any reason, storing a (char*) into an array of longs is not illegal. (w/ ISO AFAIK)
The opposite is against ISO, when the dest object is too small.
After all, the low level I/O only deals with a pointer to an address, and couldn't possibly
know _whom_ this address space is supposed to belong to in some cases ?

But, indeed, storing an ASCII string into an array of longs is pure waste, unless you're working
on some specifics of CSW or similar wrappers for USB.

Best Regards,
Kris

-----Original Message-----
From: m... [mailto:m...] On Behalf Of Clifford Heath
Sent: Saturday, 25 November 2006 4:13 PM
To: m...
Subject: Re: [msp430] Re: Printf 'long' format specifications

lewis wrote:
> I tried the following code
> unsigned long samples[20];
> long lTest ;
> lTest = 1001;
> i = sprintf(samples,"%ld",lTest);
> I ran the code using teh simulator but i get an incorrect result in
> the output buffer.

The output buffer should be char[20], not unsigned long[20].

I'm a bit alarmed that the compiler didn't prevent you from
compiling it - please read the manual and find out how to:
* require function prototypes
* issue all warnings
* #include the required files (stdio.h in this case)

Then, don't try to run code that compiles with warnings, and
you'll save yourself a lot of time.

Yahoo! Groups Links
Microbit wrote:
> Why should the compiler alarm ?
> I don't see any reason, storing a (char*) into an array of longs is not illegal. (w/ ISO AFAIK)
> The opposite is against ISO, when the dest object is too small.

Sorry, but you're confused with the ability to store a char into a
long. sprintf has no way to know that the *pointer* passed is to an
array of objects of sizeof(long), so it assumes it has a valid char*,
and stores the resultant string as ASCII bytes packed 4 to each long,
in a sequence that's defined by the machine's endian-ness. Which is
almost certainly what lewis is seeing in the simulator, but he can't
see the ASCII values because they're packed 4 to a long.

Oh, and it *is* illegal to pass a long* where a char* is expected,
unless you provide a cast and know how to predict the result.

> But, indeed, storing an ASCII string into an array of longs is pure waste,

That's not what happens here. lewis' code might generate 12 bytes
including the NUL ("-2147483648"), which will use 3 of the longs he
passed, not 12. But if you include stdio.h, it won't compile without
warnings.

Clifford Heath.
Kris,

> Why should the compiler alarm ?

It should and does-if the prototypes have been brought in! And if they
haven't it warns you that you're calling a function without a prototype.

> I don't see any reason, storing a (char*) into an array of
> longs is not illegal. (w/ ISO AFAIK) The opposite is against
> ISO, when the dest object is too small.
> After all, the low level I/O only deals with a pointer to an
> address, and couldn't possibly know _whom_ this address space
> is supposed to belong to in some cases ?
>
> But, indeed, storing an ASCII string into an array of longs
> is pure waste, unless you're working on some specifics of CSW
> or similar wrappers for USB.

The point is that characters will be dumped into the first long making it a
"big" number and there will be a terminating zzero somewhere in one of the
bytes of one of the longs. The OP should actually learn C on a PC before
doing it embedded.

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors
Clifford,

> lewis wrote:
> > I tried the following code
> > unsigned long samples[20];
> > long lTest ;
> > lTest = 1001;
> > i = sprintf(samples,"%ld",lTest);
> > I ran the code using teh simulator but i get an incorrect result in
> > the output buffer.
>
> The output buffer should be char[20], not unsigned long[20].
>
> I'm a bit alarmed that the compiler didn't prevent you from
> compiling it - please read the manual and find out how to:

It used to raise errors on assigning incompatible pointer types (long * and
char * are incompatible) but we have to compile so many broken legacy
programs that, by customer demand, it was reduced to a warning with an
option to treat warnings as errors.

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors
Hi Clifford, Paul,

> Sorry, but you're confused with the ability to store a char into a
> long. sprintf has no way to know that the *pointer* passed is to an

No, I wasn't.
I referred to a (char *) (I enclosed w/ parentheses to indicate I meant a char * ).
But I meant that you can store the contents of a char * into _any_ (writeable) address, including
samples or IOW &samples[0]. (of course, if it's been typecasted !! Hmm)
But I indeed overlooked that the prototype of the function is (should be) there, and
that a char* and long* are incompatible pointer types. Sorry.

But then again, I'd never declare a long array to store an ASCII string :-)
Perhaps it's harder to imagine what happens when something's done _wrong_ instead of right,
rather than the other way around, so to say, dunno.

Best Regards,
Kris

-----Original Message-----
From: m... [mailto:m...] On Behalf Of Clifford Heath
Sent: Saturday, 25 November 2006 6:03 PM
To: m...
Subject: Re: [msp430] Re: Printf 'long' format specifications

Microbit wrote:
> Why should the compiler alarm ?
> I don't see any reason, storing a (char*) into an array of longs is not illegal. (w/ ISO AFAIK)
> The opposite is against ISO, when the dest object is too small.

Sorry, but you're confused with the ability to store a char into a
long. sprintf has no way to know that the *pointer* passed is to an
array of objects of sizeof(long), so it assumes it has a valid char*,
and stores the resultant string as ASCII bytes packed 4 to each long,
in a sequence that's defined by the machine's endian-ness. Which is
almost certainly what lewis is seeing in the simulator, but he can't
see the ASCII values because they're packed 4 to a long.

Oh, and it *is* illegal to pass a long* where a char* is expected,
unless you provide a cast and know how to predict the result.

> But, indeed, storing an ASCII string into an array of longs is pure waste,

That's not what happens here. lewis' code might generate 12 bytes
including the NUL ("-2147483648"), which will use 3 of the longs he
passed, not 12. But if you include stdio.h, it won't compile without
warnings.

Clifford Heath.

Yahoo! Groups Links

The 2024 Embedded Online Conference