Adding leading zeros to HEX

Hi
I want to add the initial 0 to make sure all values are 2 characters long for a mac address, (not the 0x part)
Any suggestions of how it work here?

  String dataString = "";
                dataString += String(mac[0], HEX);
                dataString += ":";
                dataString += String(mac[1], HEX);
                dataString += ":";
                dataString += String(mac[2], HEX);
                dataString += ":";
                dataString += String(mac[3], HEX);
                dataString += ":";
                dataString += String(mac[4], HEX);
                dataString += ":";
                dataString += String(mac[5], HEX);
  Serial.println(dataString);

you are much better off with this:

char dataString[50] = {0};
sprintf(dataString,"%02X:%02X:%02X:%02X:%02X:%02X",mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
Serial.println(dataString);

%X means replace this with the hex format of the corresponding variable. (the first %X uses the first variable mac[0], and so on). The 02 between the % and the X specifies that it should be padded with 0's to 2 characters long. So for example values of mac[n]: 0,1,10,16, would be printed as: 00, 01, 0A, 10.

You'll be far better off in the long run learning how to use cstrings rather than the String class.

I second TCWORLD's opinion that sprintf is almost always a better solution to formatting than the String class. I like snprintf a little better since it is safer but in this case you will never overflow the character array.

In addition to being simpler the sprintf solution takes less memory. This sketch takes 4070 bytes and has no zero fill.

uint8_t mac[] = {110, 5, 30, 0, 50, 12};
void setup() {
  Serial.begin(9600);
  String dataString = "";
  dataString += String(mac[0], HEX);
  dataString += ":";
  dataString += String(mac[1], HEX);
  dataString += ":";
  dataString += String(mac[2], HEX);
  dataString += ":";
  dataString += String(mac[3], HEX);
  dataString += ":";
  dataString += String(mac[4], HEX);
  dataString += ":";
  dataString += String(mac[5], HEX);
  Serial.println(dataString);
}
void loop() {
}

This sketch takes 3528 bytes and is very simple.

uint8_t mac[] = {110, 5, 30, 0, 50, 12};
void setup() {
  Serial.begin(9600);
  char dataString[50] = {0};
  sprintf(dataString, "%02X:%02X:%02X:%02X:%02X:%02X",mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
  Serial.println(dataString);
}
void loop() {
}

If memory is a problem you can do something like this which takes 2220 bytes but is not a general solution.

uint8_t mac[] = {110, 5, 30, 0, 50, 12};
void setup() {
  Serial.begin(9600);
  for (uint8_t i = 0; i < 6; i++) {
    if (i) Serial.write(':');
    if (mac[i] < 16) Serial.write('0');
    Serial.print(mac[i], HEX);
  }
  Serial.println();
}
void loop() {
}

You'll be far better off in the long run learning how to use cstrings rather than the String class.

Of course, learning to use C strings would be even better.

Note: This is a old topic, but I think it is on topic and was the first I found so I thought it was best to keep it together with the other methods.

Here is a method to print HEX digits with leading zeros that uses shifts and masks instead of strings.

Calling:

    unsigned long DATA = thePacket.asInt;

    Serial.print("  1-Digit=");  crPrintHEX(DATA,1);
    Serial.print("  4-Digits="); crPrintHEX(DATA,4);
    Serial.print("  7-Digits="); crPrintHEX(DATA,7);
    Serial.print("  8-Digits="); crPrintHEX(DATA,8);

Output:

Prints: 1-Digit=E    4-Digits=017E    7-Digits=000017E    8-Digits=0000017E

Subroutine:

//---------------------------------------------------------------------------------
// crPrintHEX
//---------------------------------------------------------------------------------

void crPrintHEX(unsigned long DATA, unsigned char numChars) {
    unsigned long mask  = 0x0000000F;
    mask = mask << 4*(numChars-1);
    
    for (unsigned int i=numChars; i>0; --i) {
         Serial.print(((DATA & mask) >> (i-1)*4),HEX);
         mask = mask >> 4;
        }
        
    Serial.print("  ");
}

mrjonny2:
Hi
I want to add the initial 0 to make sure all values are 2 characters long for a mac address, (not the 0x part)
Any suggestions of how it work here?

  String dataString = "";

dataString += String(mac[0], HEX);
                dataString += ":";
                dataString += String(mac[1], HEX);
                dataString += ":";
                dataString += String(mac[2], HEX);
                dataString += ":";
                dataString += String(mac[3], HEX);
                dataString += ":";
                dataString += String(mac[4], HEX);
                dataString += ":";
                dataString += String(mac[5], HEX);
  Serial.println(dataString);

If you are building a text message to print then just print each part in turn instead.

Serial.print( "Sentence start " ); // these three lines print one line of text
Serial.print( "* middle *" ); // serial data does not have to be pre-buffered
Serial.println( " end" ); // serial data arrives when it's ready which can be in pieces

Don't use Strings on Arduino. They become a bad habit.

String objects are more suited to PC's with lots of memory to waste.
And they are "easier" because you don't have to learn about char arrays and the string commands.
But you learn about arrays anyway or you code beginning-intro, and you don't have to use string.h.

A String object just to add a character, makes a new copy of itself with the added char then deletes the old copy, leaving a hole in your heap. It used to do worse but that's been fixed which still doesn't "fix" Strings! Add another character and it makes a new copy, that doesn't fit in the hole, on top of the heap, pushing towards the stack that grows from top of memory down. If the heap or stack ever crosses into the other, the least you get is data corruption but when heap overwrites stack the crash is usually next.

Use C strings where you need them. Find ways around when you can.

A C string is a char array. Char is the signed 8 bit variable type.
Text in the string is ASCII code characters (there's ASCII charts on Google) that end with a char == 0.
If you can understand arrays then you can deal with C strings.

@BlueCab - thanks for this function, super helpful!

I found out that after some updates (IDE & libraries) my old code returned empty mac string instead of hex numbers.

It appears that this:
sprintf(dataString, "%02X:%02X:%02X:%02X:%02X:%02X",mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);

needs to be rewritten using lowercase x:
sprintf(dataString, "%02x:%02x:%02x:%02x:%02x:%02x",mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);

easiest method:

if (incomingByte < 16) Serial.print('0'); <<<< just add this code to add the 0 before printing the hex char.
Serial.print(incomingByte,HEX);

If you want to show 0 - F on Serial Monitor as 00 - 0F, then the codes are:

if(dataByte < 0x10)
{
    Serial.print('0'):
}
Serial.print(dataByte);