Char substring, not String substring

Is there an equivalent to substring for char arrays? For instance in the code below the myString.substring(4, 6) gives me gives me a result of 56 but I can’t find a function which does the same for myChar.

Any help would be appreciated, all the searches that I have done come up with String solutions rather than char solutions.

  String myString="123456789";
  Serial.println(myString);
  Serial.println(myString.substring(4, 6));
  Serial.println();
  char myChar[10]="123456789";
  Serial.println(myChar);

You'd use a combination of array indexing and functions from the standard c-string library:
https://en.cppreference.com/w/cpp/header/cstring
https://cplusplus.com/reference/cstring/

If you just want to print part of a string consider this

    Serial.write(myChar + 4, 2);

These are really useful links but there doesn't appear to be a command to find parts of an array as far as I can see.

What I really want to do is divide a char into sub chars. I juat tried

  char subChar[4];
  subChar=(myChar + 4, 2);

but I got the error

error: incompatible types in assignment of 'int' to 'char [4]'

I'd use strncpy().

Did you read what I said ?

That is not what you want to do so the simple example that I posted will not work

strncpy() only appears to give parameters for the length from the start of the char and not a start and end location.

I've found a work around, it's not pretty but it works.

  char myChar[10]="123456789";
  Serial.println();
  Serial.println(myChar);

  char subChar[4];
  String tempString=(String(myChar).substring(4, 6));
  tempString.toCharArray(subChar,sizeof(tempString));
  Serial.println(subChar);

I just thought that I would try it.

Ugly.

The name of an array decays to a pointer to the first element. So, you can use standard pointer arithmetic:

  char myChar[] {"123456789"};
  char subString[6] {'\0'};
  strncpy(subString, myChar+4, 2);
  Serial.println(myChar);
  Serial.println(subString);

Output:

123456789
56
1 Like

Yes

just a note to add that the '0' initialisation of the subString is important otherwise subString would likely not be properly terminated with the null char after the strncpy.

1 Like

A really big thanks for that. That's exactly what i was looking for but i couldn't figure out the syntax.
Thanks again.

if you want to go a small bit faster esp if your buffer is long (no need to put null characters everywhere in the buffer to override them just later and just really need one at the end

  char myChar[] {"123456789"};
  byte numberOfBytesOfInterest = 2;
  char subString[numberOfBytesOfInterest+1] ;
  strlcpy(subString, myChar+4, sizeof subString); // strlcpy will also ensure you don't overrun the buffer

Thanks for the help, I was trying to modify a sketch to find MAC addresses so that I can copy and paste to avoid typos. I get this now:

MAC Address EC:FA:BC:9F:21:EB
ESP Now MAC Address {0xEC, 0xFA, 0xBC, 0x9F, 0x21, 0xEB}

//#include "WiFi.h"
#include <ESP8266WiFi.h>
char MACchar[19];
char MAC_Parts[5][3];
 
void setup(){
  Serial.begin(115200);
  WiFi.mode(WIFI_AP_STA);
  delay(2000);
  
  WiFi.macAddress().toCharArray(MACchar, 19);
  Serial.print("MAC Address             ");
  Serial.println(MACchar);

  
  int x =0;
  for (int i=0;i<=5;i++)
  {
    strlcpy(MAC_Parts[i], MACchar+x, sizeof MAC_Parts[i]);
    //Serial.println(MAC_Parts[i]);
    x=x+3;
  }

  Serial.print("ESP Now MAC Address    {0x");
  Serial.print(MAC_Parts[0]);
  Serial.print(", 0x");
  Serial.print(MAC_Parts[1]);
  Serial.print(", 0x");
  Serial.print(MAC_Parts[2]);
  Serial.print(", 0x");
  Serial.print(MAC_Parts[3]);
  Serial.print(", 0x");
  Serial.print(MAC_Parts[4]);
  Serial.print(", 0x");
  Serial.print(MAC_Parts[5]);
  Serial.println("}");
}


 
void loop(){
}

{0xEC, 0xFA, 0xBC, 0x9F, 0x21, 0xEB} has 6 hex values not 5

you are overflowing

But is it not 0 to 5 and therefore, 6 parts?

when you define an array you give the number of elements so 6 elements, going from index 0 to index 5

char MAC_Parts[6][3];
the 3 means you can have 2 significant characters, the third one will be the trailing null char added by strlcpy()


for your code note that you could just iterate through the String using String functions to extract the pieces

something like this, typed here so let you test it.

String mac = "EC:FA:BC:9F:21:EB";

void setup() {
  Serial.begin(115200);
  Serial.print("ESP Now MAC Address    {");
  int pos = 0, colonPos = 0;

  while ((colonPos = mac.indexOf(':', pos)) >= 0) {
    if (pos != 0) Serial.print(", ");
    Serial.print("0x");
    Serial.print(mac.substring(pos, colonPos));
    pos = colonPos + 1;
  }

  if (mac.charAt(pos) != '\0') { // handle the last one which does not have a colon afterwards
    if (pos != 0) Serial.print(", ");
    Serial.print("0x");
    Serial.print(mac.substring(pos));
  }
  Serial.print("}");
}

void loop() {}

or you could go and print until you find a column or a null char and build the text as you go.

String mac = "EC:FA:BC:9F:21:EB";

void setup() {
  Serial.begin(115200);
  Serial.print("ESP Now MAC Address    {");

  int pos = 0;
  bool done = false;
  while (not done) {
    switch (mac.charAt(pos)) {
      case '\0': Serial.println("}");  done = true; break;
      case ':' : Serial.print(", 0x"); break;
      default  : if (pos == 0) Serial.print("0x"); Serial.write(mac.charAt(pos)); break;
    }
    pos++;
  }
}

void loop() {}

plenty of options

I keep learning about programming in bits. Is there a definitive reference book on C++? I'm sure there are a lot but is there one which is the bible?

When i got my comadore 64, a million years ago, it came with a book covering all the syntax. I read it front to back, and whilst it didn't all stick, enogh did so that i new where to look when I had a problem.

I'm a bit old fashioned and I prefer paper reference books.

Unfortunately, C++ is a much larger and more complex language than Comadore 64 BASIC. A "definitive" book would be huge and would serve neither beginners nor experienced programmers well.

I understand the appetite for a paper format but would advise to get started first with on line materials if you are a hands on learner

There is a lot available like C++ Introduction to get you started where the web site lets you type and try code directly on line. It helps anchor knowledge and you don’t get distracted by terminal command lines and files on your machine etc… (but there is advertising).

you can get a book for paper reference as well if you are more of a conceptual learner willing to get acquainted with theoretical knowledge without even trying everything - that works for some too esp if you master a few other OO programming languages. I heard good things about The C++ Primer(not c++ primer plus) as a first book. You also have Scott Meyers' Effective C++ books worth looking at. Of course any good Bookshelf would not be complete without the original book by Bjarne Stroustrup.

My experience has been though that the language and libraries are so rich now that searching on line (cppreference.com and https://cplusplus.com/ are good sources) or even asking targeted narrow questions to chatGPT will open new horizons much faster than a 1000 page book.

Investing time in having a good grasp on the syntax, grammar (understanding statements) and the role of types is going a long way. Don’t cut corners there.

Of course if you apply your skills in the arduino world and have questions, the forum is also happy to help out.

Have fun with C++!