This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Re: Sprintf error

I have written a routine to update an array using sprintf statement but after the execution the array doesnt seem to update. I am clueless where i have made the mistake. Can anybody help me? The program is given below.


#include<reg669.h>
#include<stdio.h>

xdata unsigned char *Arr[3];
xdata unsigned int  Val = 1;
xdata unsigned int  Val1 = 2;

void main(void) { S0CON = 0x50; //SERIAL COM IN MODE 1 TMOD = 0x20; //TIMER 1 IN AUTO RELOAD MODE TH1 = 0xFD; //BAUD RATE IS 19200 TL1 = 0x00; TR1 = 1; //ENABLE TIMER 1 Arr[0] = "LCD Testing "; Arr[1] = "Programming of LCD"; sprintf(Arr[1],"%s%u",Arr[1],Val); Arr[2] = "Sprintf testing "; sprintf(Arr[2],"%s%u",Arr[2],Val1); SBUF=' '; printf(Arr[0]); TI_0 = 0; Delay(1000); SBUF=' '; printf(Arr[1]); TI_0 = 0; Delay(1000); SBUF=' '; printf(Arr[2]); TI_0 = 0; Delay(1000); while(1); }

The 1st printf works fine whereas for the 2nd and 3rd printf statments the integer value doesnt come alont with string. I dont know the reason....

I am clueless regarding the mistake i have done.

Parents Reply Children
  • Why not just use printf directly:

         SBUF=' ';
         printf( "LCD Testing    " );
         TI_0 = 0;
         Delay(1000);
    
         SBUF=' ';
         printf( "Programming of LCD %u", Val );
         TI_0 = 0;
         Delay(1000);
    
         SBUF=' ';
         printf( "Printf testing %u", Val1 );
         TI_0 = 0;
         Delay(1000);
    
    

  • Printing directly is simple and straight forward. But i need to display 15 datas during run time of a program in the LCD. In order to view the datas user will use "UP" or "Down" key. So when user uses that i need to display it accordingly.

    Thats is y i declared array pointer and the array element i will use a variable to increment or decrement the value according to the UP or Down key pressing.

    Hence based on that the display will change and user can review the datas.

  • You will use a lot of unnecessary XDATA space in this approach for storing the complete string, when only the value part of it actually changes!

    Of course, if you have plenty of XDATA space, that may not be a problem for you.

    In this case, you need the array of strings - not just an array of pointers!

  • "But i need to display 15 datas during run time of a program in the LCD."

    If they change at run time, you are going to have to rebuild the string with the new value each time it is requested for display, aren't you?

    You can't just build the strings once and then just select one for display, can you?

    So I can't see how your approach will actually save anything over using printf directly?

  • Yep Andy. U r rite..Out of 20 characters a part of it already fixed as strings...Only part i need to append along with the strings.

    For example,

    here is the string fixed ="On time = "
    along with that i need to add "60" after equal to symbol as this 60 is represented as integer and kept in another variable.

    So i used,sprintf statment to append the both then comes the problem when using array of pointers...

  • #include<reg669.h>
    #include<stdio.h>
    
    xdata unsigned char *Arr[3][20];
    xdata unsigned int  Val = 1;
    xdata unsigned int  Val1 = 2;
    

    void main(void) { S0CON = 0x50; //SERIAL COM IN MODE 1 TMOD = 0x20; //TIMER 1 IN AUTO RELOAD MODE TH1 = 0xFD; //BAUD RATE IS 19200 TL1 = 0x00; TR1 = 1; //ENABLE TIMER 1 Arr[0][20] = "LCD Testing "; Arr[1][15] = "Programming of LCD"; sprintf(Arr[1][20],"%s%u",Arr[1][15],Val); Arr[2][15] = "Sprintf testing "; sprintf(Arr[2][20],"%s%u",Arr[2][15],Val1); SBUF=' '; printf(Arr[0][20]); TI_0 = 0; Delay(1000); SBUF=' '; printf(Arr[1][20]); TI_0 = 0; Delay(1000); SBUF=' '; printf(Arr[2][20]); TI_0 = 0; Delay(1000); while(1); }

    Andy as u said i have changed the 1D array to 2D array but according the above the result was,

    LCD Testing
    Sprtinf testing 2
    Sprintf testing 2
    

    If i disable the sprintf statement and print the ouput for Arr[2][20] then the output is,

    LCD Testing
    Programming of LCD 1
    Programming of LCD 1
    

    Even though i disabled sprtinf statement for Arr[2][20].

  • Andy as u said i have changed the 1D array to 2D array but according the above the result was,

    Wrong! You have added an extra dimension to your array, but are still playing with pointers, instead of characters. Away with the star in the declaration.

    Your code:

         Arr[1][15] = "Programming of LCD";
         sprintf(Arr[1][20],"%s%u",Arr[1][15],Val);
    


    Will manage the first assign, but the line will not mean what you think it means.

    The second line - sprintf() will still not print to a text buffer, but will get an unassigned pointer to use for buffer. And even if Arr would have been correctly initialized with 15*20 pointers, the individual indices are 0..14 and 0..19, and you are making use of the index 20, i.e. the 21th entry of a dimension that has only 20 entries...

    But for the optimum, replace Val with an array of 15 entries, and build the string whenever the users presses the up or down button. Then you don't need the sprintf() at all.

  • ... and think more carefully about pointers, arrays, strings, etc

    xdata unsigned char *Arr[3][20];
    


    Should be:

    xdata unsigned char Arr[3][20];
    


    ie, an array of three 20-character strings
    (and don't forget that the 20 includes the NUL terminator - so that's only 19 usable characters)

         Arr[0][20] = "LCD Testing    ";
    


    No, you can't do that!

    You need to copy that text into the string

         Arr[1][15] = "Programming of LCD";
         sprintf(Arr[1][20],"%s%u",Arr[1][15],Val);
    


    Again, you can't do that!

    you need something like:

         sprintf( Arr[1], "Programming of LCD %u", Val );
    


    and you will need to repeat that each time you want to display a new value of 'Val'...

    I still don't think this array of strings is helping you - you are still going to have to rebuild each string immediately before you display it - so you might just as well use printf directly!

  • Can't you just use something like:

    void display_a_value( unsigned char value_id )
    {
       switch( value_id )
       {
          case 0: printf( "this value is: %u" this_value );
                  break;
    
          case 1: printf( "that value is: %u" that_value );
                  break;
    
          case 2: printf( "the other value is: %u" the_other_value );
                  break;
    
          etc...
       }
    }
    

    Of course, you'd need some meaningful identifiers, and there's room for some optimisation - but that's the basic idea.

    Always start with the basics; optimise later!