Strange behaviour defining variabls and using sscanf

I found the blow code from SurferTim, and though it works asis, it didn't in my project, it changed the netmask and gateway so they start wit 0 (zero), I found out that it was related to the order i had defined my variables. mine are like this.

byte myMac[6];
byte myIP[4];
byte myDNS[4];
byte myGW[4];
byte myNM[4];

I am not an educated programmer, but there's have to an other explanation than the order??
Hope someone would take the time to clear this out for me......

I'am using Arduion 1.0.6 on a Mega and a WiFi shield W5100

To use the code this needs to be on the SD card in file "CONFIG1.DAT"

DE:AD:BE:EF:FE:EE
192.168.100.178
255.255.255.0
192.168.100.1
192.168.100.1
#include <SD.h>
#include <SPI.h>
#include <Ethernet.h>

byte myMac[6];
byte myIP[4];
byte myNM[4];
byte myGW[4];
byte myDNS[4];

void setup() {
 Serial.begin(115200);  

 pinMode(10,OUTPUT);
 digitalWrite(10,HIGH);

 if(!SD.begin(4)) Serial.println("SD fail");
 else Serial.println("SD ok");

 File fh = SD.open("CONFIG1.DAT",FILE_READ);
 char netBuffer[32];
 
   if(!fh) {
     Serial.println("SD open fail");
     return;    
   }
 int chPos = 0;
 int lineNo = 0;
 
 while(fh.available()) {
   char ch = fh.read();
   if(ch == '\r') {
     chPos = 0;

     switch(lineNo) {
       case 0:
//          Serial.print("mac ");        
 sscanf(netBuffer,"%2x:%2x:%2x:%2x:%2x:%2x",&myMac[0],&myMac[1],&myMac[2],&myMac[3],&myMac[4],&myMac[5]);  
       break;

       case 1:
//          Serial.print("ip ");        
 sscanf(netBuffer,"%u.%u.%u.%u",&myIP[0],&myIP[1],&myIP[2],&myIP[3]);  
       break;

       case 2:
//          Serial.print("netmask ");        
 sscanf(netBuffer,"%u.%u.%u.%u",&myNM[0],&myNM[1],&myNM[2],&myNM[3]);  
       break;

       case 3:
//          Serial.print("gateway ");        
 sscanf(netBuffer,"%u.%u.%u.%u",&myGW[0],&myGW[1],&myGW[2],&myGW[3]);  
       break;

       case 4:
//          Serial.print("dns ");        
 sscanf(netBuffer,"%u.%u.%u.%u",&myDNS[0],&myDNS[1],&myDNS[2],&myDNS[3]);  
       break;
     }

     Serial.println(netBuffer);
     lineNo++;
   }
   else if(ch == '\n') {
      // do nothing
   }
   else if(chPos < 31) {
     netBuffer[chPos] = ch;
      chPos++;
     netBuffer[chPos] = 0;
   }
 }
 
 fh.close();

 int x;
 
 Serial.print("\r\nmac ");
 for(x=0;x<6;x++) {
   Serial.print(myMac[x],HEX);
   if(x<5) Serial.print(":");
 }

 Serial.print("\r\nip ");
 for(x=0;x<4;x++) {
   Serial.print(myIP[x],DEC);
   if(x<3) Serial.print(".");
 }

 Serial.print("\r\nnetmask ");
 for(x=0;x<4;x++) {
   Serial.print(myNM[x],DEC);
   if(x<3) Serial.print(".");
 }

 Serial.print("\r\ngateway ");
 for(x=0;x<4;x++) {
   Serial.print(myGW[x],DEC);
   if(x<3) Serial.print(".");
 }

 Serial.print("\r\ndns ");
 for(x=0;x<4;x++) {
   Serial.print(myDNS[x],DEC);
   if(x<3) Serial.print(".");
 }

 Serial.println("\r\nStarting ethernet");
 Ethernet.begin(myMac,myIP,myDNS,myGW,myNM);
 digitalWrite(10,HIGH);
 
 Serial.println(Ethernet.localIP());
}

void loop() {
}
and though it works asis, it didn't in my project, it changed the netmask and gateway so they start wit 0 (zero)

So, you posted the code that works, and you want us to guess what the code that doesn't work looks like, and then to guess why it doesn't work, without seeing any serial output? How well do you suppose that is going to work?

Not very well would be my guess.

sscanf scans a character array (netBuffer in your case) using the given format.

I don't see where you store data in netBuffer so you are basically scanning an uninitialized array of characters that more than likely is not null terminated. Unexpected behaviour will be the result.

Wild guess is that you actually wanted to use sprintf instead of sscanf.

byte myMac[6];
byte myIP[4];

sscanf(netBuffer,"%2x:%2x:%2x:%2x:%2x:%2x",
       &myMac[0],&myMac[1],&myMac[2],&myMac[3],&myMac[4],&myMac[5]);

sscanf(netBuffer,"%u.%u.%u.%u",&myIP[0],&myIP[1],&myIP[2],&myIP[3]);

%x and %u store an int value to the address you give, but you have given addresses to a byte array, so the stored values get clobbered by the following ones.

Actually what happens is that an extra 0 (MSB of the value) is written after the correct byte value

Use the hh modifier to store to byte-sized variables.

sscanf(netBuffer,"%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx",
       &myMac[0],&myMac[1],&myMac[2],&myMac[3],&myMac[4],&myMac[5]);

sscanf(netBuffer,"%hhu.%hhu.%hhu.%hhu",&myIP[0],&myIP[1],&myIP[2],&myIP[3]);

Thanks for all your replies

@PaulS
Sorry for not being explicit in my post.

When I use the original code i get this serial output:
SD ok

mac DE:AD:BE:EF:FE:EE
ip 192.168.100.178
netmask 255.255.255.0
gateway 192.168.100.1
dns 192.168.100.1

When I change the order of these 5 variables in the original code to this
byte myMac[6];
byte myIP[4];
byte myDNS[4];
byte myGW[4];
byte myNM[4];

I get this serial output
SD ok

mac DE:AD:BE:EF:FE:EE
ip 192.168.100.178
netmask 0.255.255.0
gateway 0.168.100.1
dns 192.168.100.1

@Sterretje
Here i store the netBuffer chr by chr

netBuffer[chPos] = ch;

@oqibidipo
This nailed i :slight_smile:
I didn't get this from the library