[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [avr-gcc-list] sprintf
From: |
Dave Hylands |
Subject: |
Re: [avr-gcc-list] sprintf |
Date: |
Thu, 26 Feb 2009 17:20:21 -0800 |
Hi Dave,
> So I was using sprintf to create some data to send to the LCD, by way of
> lcd_puts.
> I had a pair of arrays, A_String[17], and B_String[17] which I filled
> using two loops.
>
> I hit some problems when I tried to consolidate this into one loop.
> The symptom was that the second string wouldn't display, but it would if I
> had the two routines in separate loops.
> I'm creating a simple bar graph, Data_A and Data_B have some value that is
> roughly between 0 and 16* the Step value.
>
> for (i=0; i<16; i++)
> {
> if ((Step * i) < Data_A) {
> sprintf((A_String+i), "%c", 0xFF);
> } else {
> sprintf((A_String+i), "%c", 0x20);
> }
> if ((Step * i) < Data_B) {
> sprintf((B_String+i), "%c", 0xFF);
> } else {
> sprintf((B_String+i), "%c", 0x20);
> }
> }
Wow - using sprintf to write single character values is an awfully
expensive way of doing things.
I would have coded:
for (i=0; i<16; i++)
{
if ((Step * i) < Data_A) {
A_String[i] = 0xFF;
} else {
A_String[i] = 0x20;
}
if ((Step * i) < Data_B) {
B_String[i] = 0xFF;
} else {
B_string[i] = 0x20;
}
}
A_String[16] = 0;
B_String[16] = 0;
>
> lcd_home();
> lcd_gotoxy(0,0);
> lcd_puts(A_String); // String must be null terminated.
> lcd_gotoxy(0,1);
> lcd_puts(B_String);
> In the above implementation, B_String would not show up on the display, but
> A_String would..
>
> Below is the version that worked, the only difference is that the A string
> is completed before starting on the B string.
>
> for (i=0; i<16; i++)
> {
> if ((Step * i) < Data_A) {
> sprintf((A_String+i), "%c", 0xFF);
> } else {
> sprintf((A_String+i), "%c", 0x20);
> }
>
> for (i=0; i<16; i++)
> {
> if ((Step * i) < Data_B) {
> sprintf((B_String+i), "%c", 0xFF);
> } else {
> sprintf((B_String+i), "%c", 0x20);
> }
> }
>
> It turned out that I had neglected to allow for the terminating null in the
> strings, but this raises two questions for me.
>
> 1: Why doesn't sprintf((A_String+16), "%c", 0x00); drop a null into the last
> element of A_String.
This will actually drop two characters. The null character for the %c
and a terminating null character.
sprintf( foo, "%c", 'A' );
will write the A followed by a null character. So each time through
the loop you're actually writing two characters. As you discovered the
arrays need to be sized appropriately to deal with this.
> 2: Why does the separate loops case work at all?
It probably depends. The order of A_String and B_String relative to
each other and the exact size probably makes a difference. If you only
declared A_String as a 16 element array and you did
sprintf( A_String + 15, "%c", 0x20 );
then this will write the 0x20 to A_String[15] and 0x00 to
A_String[16], which will trample the byte beyond the end of A_String,
which might have been the beginning of B_String. So if you looped
writing A_String first, it would trample B_String, but the second loop
writing B_String would have fixed B_String[0] back up.
Then you amalgamated the loops, A_String[16] was trampled after
B_String[0] was written, so things didin't get corrected.
> I solved my problem by inserting the null with
> memset((A_String+16), 0, 1); and the same for B_String.
A_String[16] = 0;
would be a much more efficient way of performing the same operation.
--
Dave Hylands
Shuswap, BC, Canada
http://www.DaveHylands.com/
- [avr-gcc-list] sprintf, David VanHorn, 2009/02/26
- Re: [avr-gcc-list] sprintf,
Dave Hylands <=
- Re: [avr-gcc-list] sprintf, David VanHorn, 2009/02/26
- [avr-gcc-list] Re: sprintf, David Brown, 2009/02/27
- Re: [avr-gcc-list] Re: sprintf, Vincent Trouilliez, 2009/02/27
- Re: [avr-gcc-list] Re: sprintf, David VanHorn, 2009/02/27
- Re: [avr-gcc-list] Re: sprintf, Vincent Trouilliez, 2009/02/27
- Re: [avr-gcc-list] Re: sprintf, David VanHorn, 2009/02/27
- Re: [avr-gcc-list] Re: sprintf, David Kelly, 2009/02/27
- Re: [avr-gcc-list] Re: sprintf, Russell Shaw, 2009/02/28
- [avr-gcc-list] Re: sprintf, David Brown, 2009/02/28
- Re: [avr-gcc-list] Re: sprintf, David VanHorn, 2009/02/28