Conversion of String to Char

Hello,

I need to understand the behavior of readStringUntil().

My code when i use readStringuntil('\n'):

#include <scpiparser.h>
#include <Arduino.h>
#include <SPI.h>
#include "SdFat.h"
SdFat SD; 

struct scpi_parser_context ctx;

scpi_error_t identify(struct scpi_parser_context* context, struct scpi_token* command);
scpi_error_t print_value(struct scpi_parser_context* context, struct scpi_token* command);
scpi_error_t print1_value(struct scpi_parser_context* context, struct scpi_token* command);

File NewFile;



void setup()
{
  struct scpi_command* measure;
  struct scpi_command* value;


  /* First, initialise the parser. */
  scpi_init(&ctx);  

  /*
   * After initialising the parser, we set up the command tree.  Ours is
   *
   *    *IDN?         -> identify
   *  :MEASure
   *    :PRInt      -> print_value
   *  :VALue
   *    :PRInt1?    -> print1_value
   */
  scpi_register_command(ctx.command_tree, SCPI_CL_SAMELEVEL, "*IDN?", 5, "*IDN?", 5, identify);     //Initialise SameLevel function of Identify

  measure = scpi_register_command(ctx.command_tree, SCPI_CL_CHILD, "MEASURE", 7, "MEAS", 4, NULL);  // Command tree first child with main header name
  value = scpi_register_command(ctx.command_tree, SCPI_CL_CHILD, "VALUE", 5, "VAL", 3, NULL); 
  
  scpi_register_command(measure, SCPI_CL_CHILD, "PRINT", 5, "PRI", 3, print_value);            // Command tree subchild  to the first child

  scpi_register_command(value, SCPI_CL_CHILD, "PRINT1?", 7, "PRI1?", 5, print1_value);            // Command tree subchild  to the first child
  
   
   pinMode(15, OUTPUT); 


   Serial.begin(9600);
   Serial.println("Type any character to start");
  while (Serial.read() <= 0) {}
  Serial.print("Initializing SD card...");
  Serial.println();
 
  pinMode(SDCARD_SS_PIN, OUTPUT);
   
  if (!SD.begin(SDCARD_SS_PIN)) {
    Serial.println("initialization failed!");
    return;
  }
  
  Serial.println("initialization done.");

   
   NewFile = SD.open("commands3.txt");      // open existing file 

   if (NewFile) {   
   for(int i = 0; i<3; i++){
      char my_buffer[256];
    
     String line = NewFile.readStringUntil('\n');                              //Read from the SD card
    
     Serial.print("Line read from the sd card is :"); Serial.print(line); 
     int llength = line.length();
     //llength = llength - 1;
     Serial.println(llength);
   
     line.toCharArray(my_buffer,256);
     Serial.println("my_buffer:");
     //Serial.println(my_buffer);
    
    
 for(int j =0; j < strlen(my_buffer); j++)
{
   Serial.print(j);
   Serial.print(") ");
   Serial.println(my_buffer[j]);
}
Serial.println("=============");
     
   if(llength > 0)
    {
      scpi_execute_command(&ctx, my_buffer,llength);    
    }
    delay(100);
   }
    
    
}

}

void loop()
{
  
}


/*
 * Respond to *IDN?
 */
scpi_error_t identify(struct scpi_parser_context* context, struct scpi_token* command)
{
  scpi_free_tokens(command);

  Serial.println("MKR ZERO");
  return SCPI_SUCCESS;                                                   
}


/*
 * Respond to the command :MEASURE:PRINT
 */
scpi_error_t print_value(struct scpi_parser_context* context, struct scpi_token* command)
{
  scpi_free_tokens(command);
  Serial.println("Level 1 reached");
  return SCPI_SUCCESS;
}

/*
 * Respond to the command :VALUE:PRINT1?
 */
scpi_error_t print1_value(struct scpi_parser_context* context, struct scpi_token* command)
{
  scpi_free_tokens(command);
  Serial.println("Level 2 reached");
  return SCPI_SUCCESS;
}

Which gives a output :

Initializing SD card...
initialization done.
Line read from the sd card is :*IDN?
6
my_buffer:
0) *
1) I
2) D
3) N
4) ?
5) 

=============
Line read from the sd card is ::MEASURE:PRINT
15
my_buffer:
0) :
1) M
2) E
3) A
4) S
5) U
6) R
7) E
8) :
9) P
10) R
11) I
12) N
13) T
14) 

=============
Line read from the sd card is ::VALUE:PRINT1?14
my_buffer:
0) :
1) V
2) A
3) L
4) U
5) E
6) :
7) P
8) R
9) I
10) N
11) T
12) 1
13) ?
=============
Level 2 reached

Here , I read 3 commands written on a new line from commands3.txt file . It reads a extra character from the line (which is blank space).

I have tried withreadStringuntil('\r'): and the results are:

Initializing SD card...
initialization done.
Line read from the sd card is :*IDN?5
my_buffer:
0) *
1) I
2) D
3) N
4) ?
=============
MKR ZERO
Line read from the sd card is :
:MEASURE:PRINT15
my_buffer:
0) 

1) :
2) M
3) E
4) A
5) S
6) U
7) R
8) E
9) :
10) P
11) R
12) I
13) N
14) T
=============
Line read from the sd card is :
:VALUE:PRINT1?15
my_buffer:
0) 

1) :
2) V
3) A
4) L
5) U
6) E
7) :
8) P
9) R
10) I
11) N
12) T
13) 1
14) ?
=============

Again it takes a blank space which is obvious because it is carraige return and writes at the first position of next line.

My temporary fix is to add :

llength = llength - 1;

and a don't care character in the last command , so that it truncates it.

and after this it works fine..
but , is there any other way to fix it.