Go Down

Topic: Some *possibly* useful String functions. (Read 721 times) previous topic - next topic

MegaGamerGuy

Forgive me if this is a redudnancy of anykind, but here are some string functions:

StringLeft(String, CharCount);
StringTrimLeft(String, CharCount);
StringRight(String, CharCount);
StringTrimRight(String, CharCount);

Code: [Select]

String StringRight(String InputString, int CharCount) {
   String OutputString;
   String StringBuffer = InputString;
   while (OutputString.length() < CharCount) {
       OutputString += StringBuffer.charAt(StringBuffer.length()-1);
       StringBuffer = StringBuffer.substring(0,StringBuffer.length()-1);
   }
   StringBuffer = OutputString;
   OutputString = "";
   while (OutputString.length() < CharCount) {
       OutputString += StringBuffer.charAt(StringBuffer.length()-1);
       StringBuffer = StringBuffer.substring(0,StringBuffer.length()-1);
   }
   return OutputString;
}

String StringLeft(String InputString, int CharCount) {
   String OutputString;
   String StringBuffer = InputString;
   for (int CharIndex = 0; CharIndex < CharCount; CharIndex++) {
       OutputString += StringBuffer.charAt(CharIndex);
   }
   return OutputString;
}

String StringTrimLeft(String InputString, int CharCount) {
   String OutputString;
   String StringBuffer = InputString;
   for (int CharIndex = CharCount; CharIndex < StringBuffer.length(); CharIndex++) {
       OutputString += StringBuffer.charAt(CharIndex);
   }
   return OutputString;
}

String StringTrimRight(String InputString, int CharCount) {
   String OutputString;
   String StringBuffer = InputString;
   for (int CharIndex = 0; CharIndex < (StringBuffer.length() - CharCount); CharIndex++) {
       OutputString += StringBuffer.charAt(CharIndex);
   }
   return OutputString;
}
Peace, Love, Light, Infinity

pYro_65

Ensure you have the string library fix ( for function free(), search for it in the forum ) as you may have memory leaks after calling those methods multiple times.

You could reduce the number of temporary objects and reserve more memory to speed things along though.

From your example:
Code: [Select]

String StringTrimRight(String InputString, int CharCount) {
    String OutputString;
    String StringBuffer = InputString;
    for (int CharIndex = 0; CharIndex < (StringBuffer.length() - CharCount); CharIndex++) {
        OutputString += StringBuffer.charAt(CharIndex);
    }
    return OutputString;
}

The line 'OutputString += StringBuffer.charAt(CharIndex);' will generate many temporary variables, each one with an allocation.


It can be slightly tweaked:

Code: [Select]
String StringTrimRight(String InputString, int CharCount) {
  const int Steps = InputString.length() - CharCount;
  if( Steps < 1 ) return( "" ); //Check for invalid or complete trim
  InputString[ Steps - 1 ] = '\0';
  return( &InputString[ 0 ] );
}


This leaves the String constructor on exit to do all the looping. And only 1 temporary String object.
And as you do not pass InputString by reference, you can modify its contents without harm.

Passing String objects by reference will boost performance, however you have to copy the data to a buffer if the reference cannot change.

This construct below can help you design code that can use variable sized temporary arrays. So no large global working buffer, or oversized local buffer.
Code: [Select]

void foo( const int len ){
  char temp[ len ];
}

MegaGamerGuy

I see how you optimized the code, (thanks btw) but i dont understand how ur code reconstructs/trims the string.

oh, btw, the strings are not arrays. and im using the Arduino Due.
Peace, Love, Light, Infinity

PaulS

Code: [Select]
oh, btw, the strings are not arrays
But the array operator is overloaded in the String class, so that you can treat the String instance as an array.

The String is "trimmed" by inserting a NULL at the appropriate place. Like moving a stop sign up the street changes where cars (are supposed to) stop.

MegaGamerGuy

ok, two questions if u dont mind:

1, what is the purpose of the & in "return( &InputString[ 0 ] );" ?
2, In the sketch that im using this code i; find that if i set an 'int' to A0, then Serial.println(int) I get 54, not A0.
        is there any way to get that value back?

Thank you.
Peace, Love, Light, Infinity

PaulS

Quote
find that if i set an 'int' to A0, then Serial.println(int) I get 54, not A0.

A0 is a #define name with a value that depends on which Arduino you have. The preprocessor substitutes the value wherever the name appears, before the compiler is invoked.

So, no, printing the value of the int that was set to A0 is never going to show the string A0, because the value in the int, on a Mega IS 54.

PaulS

Quote
1, what is the purpose of the & in "return( &InputString[ 0 ] );" ?

The & is the address of operator. What is happening is that the address of InputString[ 0 ] is being returned to the caller.

You could return, for instance, &InputString[14], returning a pointer to the middle of the string.

MegaGamerGuy

so String can be used as an array? I know its basically a char* array. but the IDE likes to throw errors when i try using a String instead of a preallocated Char array
Peace, Love, Light, Infinity

PaulS

Quote
so String can be used as an array?

To some extent. You can read from/write to the String object like an array, as long as the index values are in the range of the char array that the String object wraps. The array operator was added as a convenience function, in addition to the charAt() method.

Quote
but the IDE likes to throw errors when i try using a String instead of a preallocated Char array

Depending on how you try to use a String. Do not for a minute think that adding an array operator makes a String interchangeable with a string. They are not.

MegaGamerGuy

ok, thank you for clearing some stuff up.

I will update the functions up top because i found some issues in my code not working right (such as too much being trimmed, or not enough being trimmed.

I will work with ur code to get a good understanding of how it works.
So far just reading it, i dont see any loop.
Peace, Love, Light, Infinity

pYro_65


I will work with ur code to get a good understanding of how it works.
So far just reading it, i dont see any loop.


Sorry for the late reply, my account was banned for a few days.

Code: [Select]
String StringTrimRight(String InputString, int CharCount) {
  const int Steps = InputString.length() - CharCount;
  if( Steps < 1 ) return( "" ); //Check for invalid or complete trim
  InputString[ Steps - 1 ] = '\0';
  return( &InputString[ 0 ] );
}


The function returns a string object, which is constructed using the pointer provided by "return( &InputString[ 0 ] );", which is the internal char array where String stores its data. The constructor will loop the char array till it hits a null, i.e. "InputString[ Steps - 1 ] = '\0';"

Go Up