There are multiple ways to do “strings” in C++ programs and especially in the Arduino environment.
First of all, the correct and most common way: In Arduino firmwares, use the Arduino-provided standard String
class. This class is automatically available to you when you #include <Arduino.h>
. The class is declared more specifically in WString.h
(<-- for Arduino-ESP8266).
An example usage would be
//#include <Arduino.h> above..
String stringOne = "Hello String"; // using a constant String
stringOne += "ABC"; //dynamic string concat
unsigned len = stringOne.length(); // get length
Correct, because those are no such member variables exist. The Arduino String
class has the length() method though, thus you must call it as myStrLen = myStr.length();
.
Be aware that String
uses dynamic memory, which is not too good for small-memory devices. There are blogpost about The Evils of Arduino Strings and Are Strings really that Evil? about it. Though for an ESP8266, it doesn’t really matter.
This is wrong. sizeof()
with the String myStr
variable gives you the size of an instance of a String
class. This will basically the sum of all sizes of the internal variables of the class. This will not represent the length of the string it is holding internally (to which it has a pointer). You can only sensible use sizeof
on character arrays of compile-time known length in the context of strings.
So
char myStr[] = "Hello";
unsigned len = sizeof(myStr);
will have len = 6
. Mind that a C-string contains a NUL terminator (\0
) character at the end, which counts into the sizeof
the string. strlen(myStr)
would return 5.
But we’re slightly jumping ahead.
What you’re attempting to do here is to use the string
class of the standard C++ library. This class is in the std
namespace and avaible via the string
header, so you need to do #include <string>
. Not #include <string.h>
, which will give you the C-string functions, instead of the C++ ones.
To access the class you can do
#include <string>
void func() {
std::string myString = "ABC";
}
or, by using a using namespace
declaration you can import all of std
’s classes into the global namespace. Though some consider this bad practice (namespace polution).
#include <string>
using namespace std;
void func() {
string myString = "ABC";
}
You can find a list of functions that work on std::string
in the documentation.
Note that the Arduino String
class, which most libraries use if it comes to strings, is not interchangably usable with std::string
and vice versa. These are different classes, after all. You would need to convert between them by e.g. first converting an Arduino string to a pure const char*
via .c_str()
and using that in the constructor of a std::string
, or vice-versa. (The std::string
also has the c_str()
function).
And finally, there are pure C strings, aka an array of characters or a pointer to them. In C++ you can include the C functions with either
#include <string.h>
or
#include <cstring>
See documentation here.
You of course don’t need to include any headers to get the basic “string type”, char []
or char*
, since it is a fundamental C/C++ type.
Usage of C-strings would e.g. be
#include <string.h>
void gets_c_string(const char* szString);
void test() {
//initialize string
char myString[] = "Hello, world!";
//copy into another character buffer
char myBuffer[32] = {0};
strncpy(myBuffer, myString, sizeof(myString)); //prefer strncpy over strcpy
gets_c_string(myString);
}
void gets_c_string(const char* szString) {
unsigned len = strlen(szString);
//...
}
You are free to use whatever string type you want in your program, and each of them has certain advantages and disadvantages. With C-strings you can very low-level control the strings and their sizes, wheres with String
and std::string
memory management is done on the heap and automatically for you, in a way you might or might not want (e.g., over-allocating storage space on string concat).
If you just need to pass some constant strings around, you should be using C-strings (const char*
/char[]
). If you need to perform operations like dynamic string concatination, easy searching of strings, string replacement etc., I would suggest the Arduino String
class. Only if there’s really some functionality that isn’t in Arduino String
, or when programming for platforms that don’t have an Arduino String
, I would suggest std::string
.