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...

the busybee
2,4089 silver badges18 bronze badges
asked Mar 24 at 7:10
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) : "

answered Mar 24 at 8:05
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

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.