Char * to String .. What i'm doing wrong ?

Hi there !

I’m trying to convert a array of chars to a String…

sending “Linear” to SetType()

void SetType(char * type) {

  Serial.print("Char Type : ");
  Serial.println(type);
  
  String tempString = String(type);

  Serial.print("String Type : ");
  Serial.println(tempString);
}

The console result :

Char Type : <Type>Linear
String Type :

the string convertion don’t work…
i’m missing something ?

thanks

Good job with code tags on your first posting. Not such a good job with providing complete code.

When I use the function you posted like this

void setup() {
  Serial.begin(115200);
  //either form of declaration is ok
  //char* type_parameter = "<Type>Linear";
  char type_parameter[] = "<Type>Linear";
  SetType(type_parameter);
}
void loop() {}

void SetType(char * type) {
  Serial.print("Char Type : ");
  Serial.println(type);
  String tempString = String(type);
  Serial.print("String Type : ");
  Serial.println(tempString);
}

I see this in the monitor

Char Type : Linear
String Type : Linear

What is the complete context of what you are tying to do?
Why do you need to convert the character array to a String?

Given there are some issues using Strings, why do you want to convert them?

Hey thanks for the quick answers,

i don’t posted all the code because i’ts long…

but i’m explain my context :

i’m receiving commands via Serial and i need to parse them into string to do some text replacement.
The Char replacement is tricky so i try to convert it to string.

i use this code to read Com port and put it to “receivedChars” … (basic)

void recvWithEndMarker() { // check if serial is available & save data to "receivedChars"
  static byte ndx = 0;
  char endMarker = '_'; // set the end marker of the line
  char rc;

  while (Serial.available() > 0 && newData == false) {
    rc = Serial.read();

    if (rc != endMarker) {
      receivedChars[ndx] = rc;
      ndx++;
      if (ndx >= numChars) {
        ndx = numChars - 1;
      }
      //Serial.println(receivedChars);
    }
    else {
      receivedChars[ndx] = '\0'; // terminate the string
      ndx = 0;
      newData = true;
    }
  }
}

My main rooting section :

void MainFunctionRooting() { // The main function use prefixes to root
  if (newData == true) {
    
   
    if (StrContains(receivedChars, "<X-Pulse v1>")) {
      parseData();
    }
    newData = false;
    
  }

And next :

void parseData() {      // split the data into its parts

  char * strtokIndx; // this is used by strtok() as an index

  strtokIndx = strtok(tempChars, ",");     // get the name part - the string
  Serial.print("Name : ");
  Serial.println(strtokIndx);

  strtokIndx = strtok(NULL, ",");     // get the Type part - the string
  
  SetType(strtokIndx );}

and the final section :

void SetType(char * type) {

  Serial.print("Char Type : ");
  Serial.println(type);
 
  String tempString = String(type);

  Serial.print("String Type : ");
  Serial.println(tempString);
}

i don't posted all the code because i'ts long...

You can always attach code to the post. Better yet is to make an MCVE which is a minimal complete example which can be run to verify the problem. Many times you will come to a solution when trying to create the minimal example.

What exactly is being entered from the Serial monitor?

i'm receiving commands via Serial and i need to parse them into string to do some text replacement.
The Char replacement is tricky so i try to convert it to string.

You will be better off figuring out the character array (c-string) methods for char location and replacement then getting involved with Strings on a small memory microprocessor.

Would this work for you?

void recvWithEndMarker() { // check if serial is available & save data to "receivedChars"
  static byte ndx = 0;
  char endMarker = '_'; // set the end marker of the line
  char rc;

  while (Serial.available() > 0 && newData == false) {
    ndx = Serial.readBytesUntil('_', receivedChars, sizeof(receivedChars) - 1);  // Save room for null
    receivedChars[ndx] = '\0';                                                   // Make is a string...
    newData  = true;
  }
}

I’m not sure why you’ve made ndx a static, unless you are trying to fill the string in “chunks”.

To Econjack :

no not working… added some print to see the result :

void recvWithEndMarker() { // check if serial is available & save data to "receivedChars"
  static byte ndx = 0;
  char endMarker = '_'; // set the end marker of the line
  char rc;

  while (Serial.available() > 0 && newData == false) {
    ndx = Serial.readBytesUntil('_', receivedChars, sizeof(receivedChars) - 1);  // Save room for null
    receivedChars[ndx] = '\0';                                                   // Make is a string...

    String tempString(receivedChars);
    Serial.print("test : " + tempString);

    newData  = true;
  }
}

Console result:

test :

to CattleDog :

exactly the serial line received is :

<X-Pulse v1>,<Type>Linear,<Frequency>440-500,<Rate>10-20,<Duration>1000,<ADSR>1,1

in attachment the code…

SerialTest.ino (10.4 KB)

<X-Pulse v1>,<Type>Linear,<Frequency>440-500,<Rate>10-20,<Duration>1000,<ADSR>1,1

The Char replacement is tricky so i try to convert it to string.

I don’t see in the complete code where there is “replacement”. Can you explain more.

So far, this all looks straight forward to read as you are doing, parse with strtok, and manipulate what you want without using the String class.

It will not take long to put together some example code for you if you are clear about what you want to do.

Once again, I would encourage you to put together a sketch with compiles and runs and demonstrates a problem. Focus on the reading and parsing. You can probable leave out the neopixel stuff.

hey thanks for the time you spent…

the replacement is not done at this time but it’s simply :

i want to remove the “” from my char “Linear”

i don’t find any replacement function in the cstring reference
http://www.cplusplus.com/reference/cstring/

it’s the reason why i want to convert in string…
but if i can find a reliable solution to remove it in the char array,
no further string convertion will needed…

but you’re right, i will try with a new clean code…

Your code seems to work when I send it: “,Linear_”
The results I get are:

Name : 
<X-Pulse v1>
Char Type : <Type>Linear
String Type : <Type>Linear

Here is how I turned that mess of disjoint functions into something I could compile and run.

boolean newData = false;
const int numChars = 250;
char receivedChars[numChars];
char tempChars[numChars];


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


void loop()
{
  recvWithEndMarker();
  if (newData)
  {
    strncpy(tempChars, receivedChars, numChars);


    MainFunctionRooting();
  }
}


void recvWithEndMarker()   // check if serial is available & save data to "receivedChars"
{
  static byte ndx = 0;
  char endMarker = '_'; // set the end marker of the line
  char rc;


  while (Serial.available() > 0 && newData == false)
  {
    rc = Serial.read();


    if (rc != endMarker)
    {
      receivedChars[ndx] = rc;
      ndx++;
      if (ndx >= numChars)
      {
        ndx = numChars - 1;
      }
      //Serial.println(receivedChars);
    }
    else
    {
      receivedChars[ndx] = '\0'; // terminate the string
      ndx = 0;
      newData = true;
    }
  }
}


void MainFunctionRooting()   // The main function use prefixes to root
{
  if (newData == true)
  {
    // if (StrContains(receivedChars, "<X-Pulse v1>"))
    {
      parseData();
    }
    newData = false;
  }
}


void parseData()        // split the data into its parts
{
  char * strtokIndx; // this is used by strtok() as an index


  strtokIndx = strtok(tempChars, ",");     // get the name part - the string
  Serial.print("Name : ");
  Serial.println(strtokIndx);


  strtokIndx = strtok(NULL, ",");     // get the Type part - the string


  SetType(strtokIndx);
}


void SetType(char * type)
{
  Serial.print("Char Type : ");
  Serial.println(type);


  String tempString = String(type);


  Serial.print("String Type : ");
  Serial.println(tempString);
}

i want to remove the “” from my char “Linear”

I will follow on using @johnwassers code as the base.

Once you have parsed out the second section which lies between the first and second ‘,’
strtok gives you a pointer to the start of “Linear” with a null terminator. You can easily manipulate where in the character array the pointer is pointing.

EDIT: If the headers for the different values can vary with the message such that you don’t know the number of characters in the header, then instead of using pointer manipulation you can use strtok again on the piece between the commas to find the >.

It’s not clear how you want to use the word “Linear”, but here’s an example which transfers it into a new character array. You may not want to keep the SetType function but just do what you need to do when you parse.

boolean newData = false;
const int numChars = 250;
char receivedChars[numChars];
char tempChars[numChars];

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

void loop()
{
  recvWithEndMarker();
  if (newData)
  {
    strncpy(tempChars, receivedChars, numChars);
    MainFunctionRooting();
  }
}

void recvWithEndMarker()// check if serial is available & save data to "receivedChars"
{
  static byte ndx = 0;
  char endMarker = '_'; // set the end marker of the line
  char rc;


  while (Serial.available() > 0 && newData == false)
  {
    rc = Serial.read();
    
    if (rc != endMarker)
    {
      receivedChars[ndx] = rc;
      ndx++;
      if (ndx >= numChars)
      {
        ndx = numChars - 1;
      }
      //Serial.println(receivedChars);
    }
    else
    {
      receivedChars[ndx] = '\0'; // terminate the string
      ndx = 0;
      newData = true;
    }
  }
}

void MainFunctionRooting()   // The main function use prefixes to root
{
  if (newData == true)
  {
    // if (StrContains(receivedChars, "<X-Pulse v1>"))
    {
      parseData();
    }
    newData = false;
  }
}

void parseData()// split the data into its parts
{
  char * strtokIndx; // this is used by strtok() as an index
  strtokIndx = strtok(tempChars, ",");     // get the name part - the string
  Serial.print("Name : ");
  Serial.println(strtokIndx);
  strtokIndx = strtok(NULL, ",");     // get the Type part - the string
  //demonstrate moving the pointer location
  //Serial.println(strtokIndx);
  //Serial.println(strtokIndx +6);
  SetType(strtokIndx);
}

void SetType(char* type)
{
  Serial.print("Char Type : ");
  Serial.println(type);
  Serial.print("Char Type Without Header : ");
  Serial.println(type+6);
  //transfer to another char array
  byte len = strlen(type+6); //strlen gives lenght without null
  char myUsefulPiece[len + 1]; //leave room for null
  strcpy(myUsefulPiece, type+6);//could use strncpy with len+1
  Serial.print("Transferred to new array : ");
  Serial.println(myUsefulPiece);  
}

Ah yes ! good idea ..
i will check this solution..

thanks you both John & Cattledog