String indexOf() is not working.

Hello,

Everytime I try to use a string with the indexOf() operator at the end, the arduino IDE does not recognize the indexOf() command as a special command. It doesn't highlight it orange like it does for other key words - and as a result of not recognizing it, that specific portion of my code does not work. Even looking at the example codes that come with the arduino install folders, the String.indexOf() functions in those aren't recognized. Has anyone ran into this problem before?

Thanks,
Waruma

What gets highlighted is typically a function of the entries in the keywords.txt file that comes with the library. There are occasionally keywords added to libraries, where the necessary entry in the keywords.txt file is forgotten.

What is not working in your code is impossible to determine, since you posted no code.

Thanks Paul for informing me about the keywords.txt files. Do you know which file more specifically, the indexOf() function should be in?

Here is what my code is:

String Command;
int status;
int characterposition;


void setup() {
  Serial.begin(9600);
  Serial.println("Awaiting Byte Data...");
  delay(2000);  // 2 second pause to stabilize comms
}

void loop() {
  
   while (Serial.available()) {
     delay(1);  
    
     if (Serial.available() >0) {
       char c = Serial.read();
       
       Serial.print("character entered = ");
       Serial.println(c, DEC);
       
       if (c != '\n') {
       Command += c;
       }
       else if (c == '\n') {
         Command += 0;
       }
     }
}
     
     characterposition = Command.length();
     if (characterposition > 0) {
       Serial.print("String length is: ");
       Serial.print(characterposition);
     }
     
     characterposition =  Command.indexOf(0);
     if (characterposition > 0) {
       Serial.print("CR return character located at: ");
       Serial.print(characterposition);
     }
             
     if (Command.length() >0) {
       Serial.println("");  
       Serial.println(Command);
     }
     
     if (Code == "Go") {
       status = Go();
     } 
     
     Command = "";
   
}

int Go() {
  Serial.println("");
  Serial.println("Go!");
     
  return 1;
}

The line I'm referring to is "characterposition = Command.indexOf(0);". the ide doesn't recognize that .indexOf() is a keyword.

My complier seems to have an issue with the below line in your code.

if (Code == "Go") {

I suspect there is no indexOf(int) method. You need to provide a string or char as the argument.

Why are you looking for a 0 anyway, the first one found will always be the end of the string.


Rob

Sorry - zoomkat, the code should be as follows...

String Command;
int status;
int characterposition;


void setup() {
  Serial.begin(9600);
  Serial.println("Awaiting Byte Data...");
  delay(2000);  // 2 second pause to stabilize comms
}

void loop() {
  
   while (Serial.available()) {
     delay(1);  
    
     if (Serial.available() >0) {
       char c = Serial.read();
       
       Serial.print("character entered = ");
       Serial.println(c, DEC);
       
       if (c != '\n') {
       Command += c;
       }
       else if (c == '\n') {
         Command += 0;
       }
     }
}
     
     characterposition = Command.length();
     if (characterposition > 0) {
       Serial.print("String length is: ");
       Serial.print(characterposition);
     }
     
     characterposition =  Command.indexOf(0);
     if (characterposition > 0) {
       Serial.print("CR return character located at: ");
       Serial.print(characterposition);
     }
             
     if (Command.length() >0) {
       Serial.println("");  
       Serial.println(Command);
     }
     
     if (Command == "Go") {
       status = Go();
     } 
     
     Command = "";
   
}

int Go() {
  Serial.println("");
  Serial.println("Go!");
     
  return 1;
}

Graynomad - if I search for a null character, I know it will be at the end of any input string. My intent was to scan until that null character, and the take the length-1 and try and transfer the string to another variable (string) so the null character isn't a problem at all. When I run the code in the Arduino serial monitor, as long as I have it set to "No line ending" at the bottom, everything works fine. I'll be able to branch to the "Go" subroutine no problem. If it's not set to No line ending, the serial monitor will tack on an extra CR or newline character to the end of my string - which I don't necessarily want. I was trying to do it this way and delete any null or string termination character so that I could use other serial terminals (i.e. a standalone parallax serial terminal). Does that explanation make sense?

So you just want to clean the end of the string.

You can get the length with the length() method. If you know that there is a fixed number of junk chars at the end you can do

setCharAt (s.length()-1, '\0'); // -1 or -2 depending on the number of junk chars at the end

A better way might be using trim(), this returns a string with "leading and trailing whitespace removed" but in typical crap Arduino documentation style it doesn't define what it considers to be a "whitespace" character. Normally I would expect the CR/LF at the end to be whitespace characters, but you'll have to try it to find out.

If trim() works then you're done.

If not then you have to search for the newline characters. Normally I would expect both '\r' and '\n' at the end of a string but this isn't always the case, some systems use both some just use '\n' and some just use '\r'. If you print the string out in HEX you can see what you have. If this is to be a program that has to deal with different systems then I'd search for both and use the shortest result.

However I assume you're just playing around with something for yourself and that the received string won't vary in this regard. So I'd do the HEX dump of the string, figure out how many characters to remove, then do what I suggested in the first example or maybe

newstring = oldstring.substr (0, oldstring.length()-1); // -1 or -2 depending on the number of junk chars at the end


Rob

I had to find out so did a quick test to see what trim() does.

String s = "qwerty\r\n";
String ss = s.trim();
char * ptr;
char x[100];

void setup () {
  Serial.begin(115200);
  ss.toCharArray(x, 100);
  for (ptr = x; *ptr != '\0'; ptr++)
      Serial.println (*ptr, HEX); 
      
}

void loop () {
}

trim() does remove the CR and the LF, so you can just use it.


Rob

       if (c != '\n') {
       Command += c;
       }
       else if (c == '\n') {
         Command += 0;
       }

When you get to the else statement, what values can c contain? Anything other than a ‘\n’ will have triggered the if block. Why do you need to check it again?

If you want to find the index of the NULL, you can use ‘\0’ as the indexOf() argument.

Okay, so there's a couple of options I can take to filter out the junk characters I don't want at the end. I actually tried using the indexOf() function to search for that '\0' character, but I have a problem with that command. For some reason my arduino IDE doesn't recognize that as a special keyword, and because of that it won't actually do anything when I call that command. I'll try the .trim() function to see if that one is working or not.

Thanks,
Waruma

One bit of code concerns me:

 if (c != '\n') {
  Command += c;
  }
  else if (c == '\n') {
    Command += 0;
  }

You're reading in the commands, and then null terminating when you reach \n - but what happens if the terminal still transmits? You're looping, so you'll add the next command behind this one, but the '\0' will prevent your code from ever seeing seeing it. You might want to break out of the loop after you place a null at the end, to prevent adding more characters 'behind' this.

Okay I see what you're saying. You're right, depending on what serial terminal I'm using, it may or may not send a CR or newline character after the null character has been inserted. I've modified my code now, and that section of code is no longer in it. Thanks for the heads up though. I'll post a final version of my code for review shortly.

Thanks,
Waruma