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/Network/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");
}
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
An example of use can be found in Sming/Core/Network/Http/HttpHeaders.h.
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
>
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)
- Return Value
bool
: false on memory allocation error
-
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
:
- Return Value
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 findignoreCase
: Whether search is case-sensitive or not
- Return Value
int
: index of given string, -1 if not found
-
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 findignoreCase
: Whether search is case-sensitive or not
- Return Value
int
: index of given string, -1 if not found
-
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 forignoreCase
: Whether search is case-sensitive or not
- Return Value
bool
: True if string exists in array
-
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 forignoreCase
: Whether search is case-sensitive or not
- Return Value
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
- Return Value
const
: char* nullptr if index is not valid
-
const char *
operator[]
(unsigned index) const¶ Get string at the given position.
- Parameters
index
: 0-based index of string to obtain
- Return Value
const
: char* nullptr if index is not valid
-
void
clear
()¶ Empty the array.
-
unsigned
count
() const¶ Get quantity of strings in array.
- Return Value
unsigned
: Quantity of strings
-
template<typename