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...
sprintf (s, "%04ld(0x%03lx) : ", id, id );work fine now! Don't needid2anymore. :D