0

I have the code, it's purpose is to receive the string from a comport like: Set@1234567890123456@1234567890123456@1234567890123456@1234567890123456 and translate it into four byte arrays byte user1[16], user2[16], pass1[16], pass2[16]. Here's the code:

String inString = ""; // COM port incoming data buffer

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println("Start");
}

void loop() {
  // put your main code here, to run repeatedly:
  // Receive data from com port
  while (Serial.available() > 0) {
    int inChar = Serial.read();


    if (inChar != '\n') {
      inString += (char)inChar;
    } else {
      // New line
      String Action = inString.substring(0, 3);
      if (Action == "Set") {
        SetCard(inString);
      } else if (Action == "Get") {
        Serial.println("1");
      } else {
        Serial.println(Action);
      }
      inString = "";
    }
  }
}

void SetCard(String Data) {
  Serial.println(Data);
  // Data Set@user1@user2@pass1@pass2
  // Set@1234567890123456@1234567890123456@1234567890123456@1234567890123456
  byte user1[16], user2[16], pass1[16], pass2[16];

  String user1str = inString.substring(4, 20);
  String user2str = inString.substring(21, 37);
  String pass1str = inString.substring(38, 54);
  String pass2str = inString.substring(55, 71);

  Serial.println("Strings");
  Serial.println(user1str);
  Serial.println(user2str);
  Serial.println(pass1str);
  Serial.println(pass2str);

  Serial.println("Arrays");
  user1str.getBytes(user1, 16);
  user2str.getBytes(user2, 16);
  pass1str.getBytes(pass1, 16);
  pass2str.getBytes(pass2, 16);


  writeByteArray(user1, 16);
  writeByteArray(user2, 16);
  writeByteArray(pass1, 16);
  writeByteArray(pass2, 16);
}

void writeByteArray(byte array[], int arrlength)
{
  for (int j = 0 ; j < arrlength ; j++) //print the block contents
  {
    Serial.write (array[j]);//Serial.write() transmits the ASCII numbers as human readable characters to serial monitor
  }
  Serial.println("");
}

When I run this code and send my string through a com port I expect the output:

Start
Set@1234567890123456@1234567890123456@1234567890123456@1234567890123456
Strings
1234567890123456
1234567890123456
1234567890123456
1234567890123456
Arrays
1234567890123456
1234567890123456
1234567890123456
1234567890123456

And yet, I receive

Start
Set@1234567890123456@1234567890123456@1234567890123456@1234567890123456
Strings
1234567890123456
1234567890123456
1234567890123456
1234567890123456
Arrays
123456789012345
123456789012345
123456789012345
123456789012345

Why? And how do I receive desired output? getBytes docs

2 Answers 2

2

Why? And how do I receive desired output? getBytes docs

The String member function getBytes() will null-terminate the string. You must add space for that.

  byte user1[17], user2[17], pass1[17], pass2[17];
  ...
  user1str.getBytes(user1, sizeof(user1));
  ...
  Serial.print((char*) user1);

That should do the trick.

3
  • Thank you. It worked. So, how can I truncate user1[17] array to user1[16] after I set it value with getBytes?
    – rfg
    Commented Mar 15, 2016 at 20:08
  • Or do I need to create a buffer array[17] and then write the first 16 elements from there to array[16]?
    – rfg
    Commented Mar 15, 2016 at 20:10
  • Come to think of it I could just for (int j = 0 ; j < sizeof(user1) ; j++) { user1[j] = user1str.charAt(j); } and it would work with 16 elements
    – rfg
    Commented Mar 15, 2016 at 20:13
1

Using String.getBytes(buffer, len) to get bytes.

"len" is the length to copy, but usually need to add 1 for the end of string '\0'.

For example:

String s = "123";
int count = s.length();  // lenth() is 3
s.getBytes(buffer, count);   // copied "12\0" => HEX(31 32 00)
s.getBytes(buffer, count + 1);   // copied "123\0" => HEX(31 32 33 00)

The official document not mentioned those above, and it's not reasonable for the modern function design.

Misunderstanding in that and waste our life so much.

5
  • toCharArray() is documented arduino.cc/reference/en/language/variables/data-types/string/…
    – Juraj
    Commented Oct 1, 2021 at 4:31
  • toCharArray(buffer, len) will still keep the last bye for 0x00 ('\0'). So if want to copy the specific length of the content, len should add 1 for '0'. Also, care the buffer length as the last damn byte.
    – Tomex Ou
    Commented Oct 1, 2021 at 4:41
  • that is what is expected for char-array (C string) (but not expected for getBytes)
    – Juraj
    Commented Oct 1, 2021 at 4:52
  • If the official document has mentioned the '\0' in details, it's fine for purpose. It's pity for none.
    – Tomex Ou
    Commented Oct 1, 2021 at 5:02
  • I am heaving difficulties reading your post and comments. How do you declare buffer?
    – scopchanov
    Commented Oct 16, 2021 at 8:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.