Tag Archives: string

Guidelines Support Library Review: string_span<T>

In a previous post I have introduced the span<T> type from the Guidelines Support Library. This is a non-owning range of contiguous memory recommended to be used instead of pointers (and size counter) or standard containers (such as vector or array). span<T> can be used with strings, but the Guidelines Support Library provides a different span implementation for various types of strings. These string span types are available in the string_span.h header.

String span types

There are several string span types defined in the string_span.h header:

  • basic_string_span: the actual implementation for a string span on which several type aliases are available:
    • string_span: a string span of char
    • cstring_span: a string span of const char
    • wstring_span: a string span of wchar_t
    • cwstring_span: a string span of const wchar_t

  • basic_zstring_span: a null terminated string span used for converting null terminated spans to legacy strings; it has several type aliases available:
    • zstring_span: a null terminated string span of char
    • czstring_span: a null terminated string span of const char
    • wzstring_span: a null terminated string span of wchar_t
    • cwzstring_span: a null terminated string span of const wchar_t

These look like a lot of classes with similar names, but the names are self explanatory (terminology is c=const, w=wide, z=null-terminated):

  • string: a string of char
  • cstring: a string of const char
  • wstring: a string of wchar_t
  • cwstring: a string of const wchar_t
  • zstring: a (zero) null-terminated string of char
  • czstring: a null-terminated string of const char
  • wzstring: a null-terminated string of wchar_t
  • cwzstring: a null-terminated string of const wchar_t

Creating a string_span

A string_span can be created in many ways, including:

(Note that in all following examples the string span is the range { L'H',L'e',L'l',L'l',L'o',L' ',L'w',L'o',L'r',L'l',L'd' } of either char or wchar_t.)

  • from a literal string

  • from a pointer

  • from a standard string

  • from an array

  • from a vector

Converting to string

To convert a string span into a string you can use the to_string() function.

Size of a string_span

Unlike span<T>, a string_span<T> only have one dimension, so the rank() method does not make make sense and is not available. However, a string span has several methods for the size of the span:

  • size() and length(): return the number of elements of the span
  • size_bytes() and length_bytes(): return the number of bytes of the span

Subspans

It is possible to create subspans from a string_span. There are several functions that do that:

  • first(): returns the sub-span with the first N elements from the original string_span
  • last(): returns the sub-span with the last N elements from the original string_span
  • subspan(): returns the sub-span within the specified range (first and last positions) of the original string_span.

Comparisons

You can use the comparison operators (==, !=, <, <=, >, >=) with two string spans. Just like in the case of span<T>, equality is checked with std::equal (two ranges are equal if every element in the first range is equal to the element corresponding to the same position in the second range) and less/greater is checked with std::lexicographical_compare() (one range is less than another if the first mismatch element in the first range is less than the element on the same position in the second range).

Element access

It is possible to access the content of a string_span either with iterators or indexes.

The standard way of converting between numbers and strings in C++11

In C++03 there was no standard way of converting numbers to strings. The best way to do that was using a std::stringstream:

One could put that into a more generic function that looks like this:

The opposite of converting a text to a number could look like this:

Of course, there was also the option of using C functions such as itoa, sprintf or atoi (or their Microsoft secure version _itoa_s, sprintf_s).

C++11 provides several standard functions for converting numbers to strings and strings to numbers, all of them available in the <string> header.

For converting numbers to strings there are two new overloaded functions: to_string() and to_wstring(). They take one argument of various numeric types (int, long, long long, double, long double, etc.) and return either a std::string or a std::wstring with the number converted to text.

These functions are actually just wrappers over sprintf and swprintf. According to the standard (section 21.5):

Each function returns a string object holding the character representation of the value of its argument that would be generated by calling sprintf(buf, fmt, val) with a format specifier of “%d”, “%u”, “%ld”, “%lu”, “%lld”, “%llu”, “%f”, “%f”, or “%Lf”, respectively, where buf designates an internal character buffer of sufficient size.

For the other way around of converting strings to numbers there are several overloaded methods (taking either a std::string or a std::wstring):

  • stoi: converts a string to a signed integer
  • stol: converts a string to a signed long
  • stoll: converts a string to a signed long long
  • stoul: converts a string to an unsigned long
  • stoull: converts a string to an unsigned long long
  • stof: converts a string to a float
  • stod: converts a string to a double
  • stold: converts a string to a long double

Functions stof, stod and stold are also just wrappers over strtod and strtold:

the first two functions call strtod(str.c_str(), ptr) and the third function calls strtold(str.c_str(), ptr). Each function returns the converted result, if any. The argument ptr designates a pointer to an object internal to the function that is used to determine what to store at *idx. If the function does not throw an exception and idx != 0, the function stores in *idx the index of the first unconverted element of str.

atoi() and atol() that convert a null-terminated byte-string (i.e. char*) to an integer or long were already available in header <cstdlib>. There is a new function available in this header called atoll() that converts a null-terminated byte string to a long long value.