CStringArray
Introduction
This is a class to manage a double NUL-terminated list of strings, such as "one\0two\0three\0"
.
It’s similar in operation to Vector<String>
, but more memory-efficient as all the data is
stored in a single String
object. (CStringArray is a subclass of String.)
You can see some examples in Sming/Core/DateTime.cpp and Sming/Core/Data/WebConstants.cpp.
Background
Each value in the sequence is terminated by a NUL character \0
.
For clarity, placing one string per line is suggested:
// ["one", "two", "three"]
CStringArray csa = F(
"one\0"
"two\0"
"three\0"
);
Note use of the F()
macro.
Assignments require a length because of the NUL characters, so this won’t work as expected:
// ["one"]
CStringArray csa =
"one\0"
"two\0"
"three\0";
When assigning sequences, the final NUL separator may be omitted (it will be added automatically):
// ["one", "two", "three"]
CStringArray csa = F(
"one\0"
"two\0"
"three"
);
Sequences may contain empty values, so this example contains four values:
// ["one", "two", "three", ""]
CStringArray csa = F(
"one\0"
"two\0"
"three\0"
"\0"
);
Adding strings
Elements can be added using standard concatenation operators:
CStringArray arr;
arr += "string1";
arr += 12;
arr += 5.4;
arr += F("data");
Be mindful that each call may require a heap re-allocation, so consider
estimating or calculating the required space and using String::reserve()
:
CStringArray arr;
arr.reserve(250);
// now add content
Use with FlashString
You can use a single FlashString
containing these values and load them all
at the same time into a CStringArray:
DEFINE_FSTR_LOCAL(fstr_list,
"a\0"
"b\0"
"c\0"
"d\0"
"e\0"
);
CStringArray list(fstr_list);
for(unsigned i = 0; i < list.count(); ++i) {
debug_i("list[%u] = '%s'", i, list[i]);
}
Note
The entire FlashString is loaded into RAM so better suited for occasional lookups or if instantiated outside of a loop.
You may find FSTR::Array
, FSTR::Vector
or FSTR::Map
more appropriate.
See FlashString for details.
Iterator support
Looping by index is slow because the array must be scanned from the start for each access. Iterators are simpler to use and much more efficient:
for(auto s: list) {
debug_i("'%s'", s);
}
For more complex operations:
CStringArray::Iterator pos;
for(auto it = list.begin(); it != list.end(); ++it) {
debug_i("list[%u] = '%s' @ %u", it.index(), *it, it.offset());
// Can use direct comparison with const char* or String
if(it == "c") {
pos = it; // Note position
}
}
if(pos) {
debug_i("Item '%s' found at index %u, offset %u", pos.str(), pos.index(), pos.offset());
} else {
debug_i("Item not found");
}
Pushing and popping
CStringArray can be used as a simple FIFO or stack using push/pop methods. Behaviour is similar to STL deque, except pop methods also return a value.
STACK:
CStringArray csa;
csa.pushBack("first value");
csa.pushBack("second value");
String popStack = csa.popBack(); // "second value"
FIFO:
CStringArray csa;
csa.pushBack("first value");
csa.pushBack("second value");
String deque = csa.popFront(); // "first value"
Note that popping values does not perform any memory de-allocation.
Comparison with Vector<String>
- Advantages
More memory efficient Uses only a single heap allocation (assuming content is passed to constructor) Useful for simple lookups, e.g. mapping enumerated values to strings
- Disadvantages
Slower. Items must be iterated using multiple strlen() calls Ordering and insertions / deletions not supported
API Documentation
-
class CStringArray : private String
Class to manage a double null-terminated list of strings, such as “one\0two\0three\0”.
Concatenation operators
-
template<typename T>
inline CStringArray &operator+=(T value) Append numbers, etc. to the array.
- Parameters
value – char, int, float, etc. as supported by String
Public Functions
-
bool add(const char *str, int length = -1)
Append a new string (or array of strings) to the end of the array.
Note
If str contains any NUL characters it will be handled as an array
- Parameters
str –
length – Length of new string in array (default is length of str)
- Returns
bool – false on memory allocation error
-
inline bool add(const String &str)
Append a new string (or array of strings) to the end of the array.
Note
If str contains any NUL characters it will be handled as an array
- Parameters
str –
- Returns
bool – false on memory allocation error
-
int indexOf(const char *str, bool ignoreCase = true) const
Find the given string and return its index.
Note
Comparison is not case-sensitive
- Parameters
str – String to find
ignoreCase – Whether search is case-sensitive or not
- Returns
int – index of given string, -1 if not found
-
inline int indexOf(const String &str, bool ignoreCase = true) const
Find the given string and return its index.
Note
Comparison is not case-sensitive
- Parameters
str – String to find
ignoreCase – Whether search is case-sensitive or not
- Returns
int – index of given string, -1 if not found
-
inline bool contains(const char *str, bool ignoreCase = true) const
Check if array contains a string.
Note
Search is not case-sensitive
- Parameters
str – String to search for
ignoreCase – Whether search is case-sensitive or not
- Returns
bool – True if string exists in array
-
inline bool contains(const String &str, bool ignoreCase = true) const
Check if array contains a string.
Note
Search is not case-sensitive
- Parameters
str – String to search for
ignoreCase – Whether search is case-sensitive or not
- Returns
bool – True if string exists in array
-
const char *getValue(unsigned index) const
Get string at the given position.
- Parameters
index – 0-based index of string to obtain
- Returns
const – char* nullptr if index is not valid
-
inline const char *operator[](unsigned index) const
Get string at the given position.
- Parameters
index – 0-based index of string to obtain
- Returns
const – char* nullptr if index is not valid
-
inline const char *front() const
Get first value in array, null if empty.
-
bool pushFront(const char *str)
Insert item at start of array.
- Parameters
str – Item to insert
- Returns
bool – false on memory error
-
const char *back() const
Get last item in array, null if empty.
-
inline bool pushBack(const char *str)
Add item to end of array.
- Parameters
str – Item to add
- Returns
bool – false on memory error
-
inline void clear()
Empty the array.
-
unsigned count() const
Get quantity of strings in array.
- Returns
unsigned – Quantity of strings
-
class Iterator
-
template<typename T>