0

I have this code, work fine!

uint32_t id , id2;
char s[64];  // Should be enough

...   
id2 = id = CAN.getCanId();
sprintf (s, "%04d  : ", id );  // !!! HERE !!!
Serial.print(s);

the output work FINE :

0031 : ...
2047 : ...
0031 : ...
2047 : ...
...

change to this line :

sprintf (s, "(0x%03x) : ", id2 );

work FINE , TOO :

(0x01f) : ...
(0x7ff) : ...
(0x01f) : ...
(0x7ff) : ...

but, IF I WROTE this :

sprintf (s, "%04d(0x%03x) : ", id , id2 );  

the output:

0031(0x000) : ...
2047(0x000) : ...
0031(0x000) : ...
2047(0x000) : ...

WHY? Why the %03x disappear ??

NOTE
I had include these :

#include <stdio.h>
#include <print.h>
#include <string.h>
#include <SoftwareSerial.h>
#include <Arduino.h>  // HC-05 BT
#include "DFRobot_MCP2515.h"

I know I can wote like this to solve :

            sprintf (s, "%04d", id );
            Serial.print(s);
            sprintf (s, "(0x%03x) : ", id2 );
            Serial.print(s);

I'm not newbie on C,
It just make me feels... weird...

2
  • 1
    why do you use uint32_t instead of int? do you plan to use larger values? do your tests work for values larger than 16 bit? Commented Mar 24 at 7:44
  • 1
    @Juraj Thanks, You Got It!! The code sprintf (s, "%04ld(0x%03lx) : ", id, id ); work fine now! Don't need id2 anymore. :D Commented Mar 24 at 8:17

1 Answer 1

3

Juraj give you a good hint at the solution. If you enable compiler warnings, the compiler will also tell you what is wrong:

warning: format ‘%d’ expects argument of type ‘int’, but argument 3
has type ‘uint32_t {aka long unsigned int}’ [-Wformat=]
     sprintf(s, "%04d(0x%03x) : ", id, id2);
                                          ^
warning: format ‘%x’ expects argument of type ‘unsigned int’, but
argument 4 has type ‘uint32_t {aka long unsigned int}’ [-Wformat=]

You are providing sprintf() two 4-byte integers. You are also telling it (via the format string) to read two 2-byte integers. The result is that it reads 4 bytes (the first integer) and interprets it as two numbers. For example, the number 31 (0x0000001f) is interpreted as 0x001f (i.e. 31) and 0x0000, in LSB-first order.

Solutions: Either you use plain int variables, or you tell sprintf() that you are giving it long integers instead, using the l prefix to the format: "%04ld(0x%03lx) : "

1
  • Yes! after change the code to sprintf (s, "%04ld(0x%03lx) : ", id, id ); , it work fine now! Thanks a lot. Commented Mar 24 at 8:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.