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

PROBLEMS WITH SPRINTF

Hi

i am having a problem with the sprintf function. i don't know what i am doing wrong.

i created a function where i use sprintf to separate the digits of a decimal number, and the first time that i called the function it works fine. The second time the sprintf starts when the first time left, and so on.

The variable looks something like this the first time: "0123"

and the second time: "0123123"

I don't know if i have to reset a pointer (or how to do it) so everytime i call the function it starts at the beginning of the array.



the code looks something like that:

void send_code (void)
{
int n;
	if (oper_code < 1000){
	n = sprintf (code_char, "%d", 0);
        }
	n += sprintf (code_char+n, "%d", oper_code);
  .
  .
  .
}



void main (void)
{
  .
  .
  .
while (1)
  {
  send_code();
  }
}
.

thanks in advance

  • hi,

    could you explain more what is wrong there? I see the only error is not initialized variable n. Maybe it helps:

    void send_code (void)
    {
    int n = 0;
    

    Regards,
    Oleg

  • Hi

    I am sorry, i should have said it, I posted only part of the code.

    The variable is initialized at n=0, but anyway, that is not the problem, the "n" is the returned value of the function, and it is the number of characters written to the buffer

    this is the definition of the variable at the beginning of the proigram, maybe it will help.

    
    int bdata oper_code;
    sbit LSB_oper_code = oper_code^0;
    
    char code_char[5];
    
    //char* pCode_char = code_char;	// pointer
    
    

    i even tried defining a pointer and use it in the function, but the results are the same.

    thanks

  • You're talking in riddles. For anybody to offer meaningful help, you absolutely have to show a reproducible test case: i.e. actual, complete source code of an example that exhibits the problem, any non-default compiler options you use, plus any input you feed it, the exact results, and possibly how you extracted those results from the running program.

    For starters: you said later that 'n' was initialized --- well, in the source you show it rather clearly is not (or rather: only half the time). You also said

    The variable looks something like this the first time: "0123"

    and the second time: "0123123"


    If so, you must have caused undefined behaviour, since code_char is only 5 characters long, so there's absolutely no way it could ever hold an 8-byte string like the above.

  • hi,

    the "n" is the returned value of the function

    Not always. n is correctly initialized only if oper_code below 1000. If at first time you call function send_code() with value above 999 then not initialized n will be used in next line:

    n += sprintf (code_char+n, "%d", oper_code);
    
    notice code_char+n

    Regards,
    Oleg

  • Again, "n" is not the problem, but anyway, here is the code and the "exact" results of the simulation on the computer, which is the same results as when I burn the chip.

    And about the size of code_char, it looked weird to me as well, but that is exactly the problem i am having, i think it keeps writing to the next position of the memory instead of going to zero.

    int oper_code;
    char code_char[5];
    
    
    void send_code (void)
    {
    
    int n;
    int p;
    n=0; p=0;
    
     if (oper_code < 1000){
     n = sprintf (code_char, "%d", 0);
     }
     n += sprintf (code_char+n, "%d", oper_code);
    
    }
    
    void main (void)
    {
      oper_code = 132;
    
      while (1)
      {
       send_code();
      }
    

    the first time: code_char = 0132
    the second time: code_char = 132132
    the third time: code_char = 132 132


    Thanks

  • code_char[] is not big enough to handle more than one send_code() invocation when oper_code is 132.

  • William,

    How are you looking at the results of this function? That is, you say that these are the results even when you burn a chip. How does the hardware attached to that chip display this value to you?

    The name of the function "send_code()" suggests to me you might be trying to send this out a serial port. If you're using "char_code" as a buffer, then you might very well be overwriting it while you're trying to send it.

    When you view the results on the computer simulation, is this in the "watch" window on the char_code variable, or are you looking at the output of a serial window?

  • Hi

    When i look at the result in the computer simulation is in the "char_code" variable in the "watch" window.

    As for when I burn the chip, ther is a subroutine that sends out to the serial port (uart) every element of the array such as code_char[0], code_char[1], etc.

    I guess the main question is "How can i tell this function "sprintf" where to start writing the result?". I have tried increasing and decreasing the size of the array but still does not work.

    Thanks

  • I can't beleive this, I replaced the zero the first time I call sprintf for a variable with them value of zero and now it works, such a stupid solution and I did not think about it before.

    Anyway, I don't see why it did not work, if somebody explain it would be greatly apprecciated.

    Here is the code:

    
    int oper_code;
    char code_char[5];
    
    
    void send_code (void)
    {
    
    int n;
    int p;
    n=0; p=0;
    
     if (oper_code < 1000){
     n = sprintf (code_char, "%d", p);
     }
     n += sprintf (code_char+n, "%d", oper_code);
    
    }
    
    void main (void)
    {
      oper_code = 132;
    
      while (1)
      {
       send_code();
      }
    




    thanks

  • Ah, that one...

    You're facing an ANSI standard violation of the Keil compiler & tools: it should send your constant zero to sprintf() as an int, but it will indeed send it as a byte. To account for that, you would have to use a different sprintf() format instead of "%d". It's all in the docs to be found.

  • "To account for that, you would have to use a different sprintf() format instead of "%d"."

    Or, if you prefer to retain portability, cast the parameter to int. My preference, however, would be to go with the original suggestion and use the Keil specific "%bd" instead.

  • or direct:

     if (oper_code < 1000){
     code_char[0]='0';
     code_char[1]=0x00;
     n = 1;
     }
    

    Regards,
    Oleg

  • Thank you all.
    You've helped a lot.

  • If your objective is just to left pad the value with zeroes in a field width of four you can get rid of n, p and the if test and use this instead:

    sprintf (code_char, "%04d", oper_code);