Show Lecture.Strings as a slide show.
// C strings char q[] = "gamma delta"; char *p = "alpha beta"; printf("%zd chars; first char is %c\n", strlen(q), q[0]); printf("%zd chars; ninth char is %c\n", strlen(p), p[8]);
11 chars; first char is g 10 chars; ninth char is t
// C++ strings string s = "ceti alpha six"; cout << s.size() << " chars; third char is " << s[2] << '\n' << s.length() << " chars; last char is " << s.back() << '\n';
14 chars; third char is t 14 chars; last char is x
s.c_str()
to extract a C string from a C++ string if needed.
char
, ending with '\0'
.
NULL
) char
, '\0'
, ends the string.
strlen
function, defined in <string.h>
,
to get a C string’s size.
strlen("Jack")
is 4, not 5.
string
, not String
'\0'
.
.size()
method to calculate the length.
string
methods.
.replace()
.insert()
I freely use C string literals, like this:
void emit(string s) { cout << "*** " << s << '\n'; } int main() { emit("Today is a lovely day."); return 0; }
*** Today is a lovely day.
"*** "
, gets sent to cout
.
"*** "s
.
"Today is a lovely day."
, got converted
to a std::string
at the point of the function call.
I suppose that has some tiny cost that could become significant
inside a loop.
char q[80] = "This is a C string.\n"; cout << q; char r[] = "foobar"; r[3] = '\0'; cout << "r is now \"" << r << "\"\n"; const char *p = "This is also a C string"; cout << p << ", length is " << strlen(p) << '\n';
This is a C string. r is now "foo" This is also a C string, length is 23
string s("useless initial value"); s = "This am a C++ string"; // mixed s[5] = 'i'; // mutable s[6] += 6; // char is integer-like cout << s << ", length is " << s.size() << '\n';
This is a C++ string, length is 20
Converting from a C-style string to a C++ string is easy, because the C++ string object has a constructor that takes a C-style string:
char chip[] = "chocolate"; string dale(chip); cout << dale << '\n';
chocolate
Converting from a C++ string to a C-style string requires a method:
string wall(30, '#'); const char *p = wall; cout << p << '\n';
c.cc:2: error: cannot convert 'std::__cxx11::string' {aka 'std::__cxx11::basic_string<char>'} to 'const char*' in initialization
string wall(30, '#'); const char *p = wall.c_str(); cout << p << '\n';
##############################
This is useful for calling an old-fashioned library function that wants a C-style string.
42
, 1.2e-24
, 'x'
, "foo"
, true
, or nullptr
.
const
variables are not literals. They’re variables that don’t vary.
char
: 'X'
.
"alpha beta gamma"
.
const char []
, or const char *
.
std::string
: "foobar"s
, with the trailing s
.
A "string literal"
is an anonymous array of constant characters.
These are equivalent:
cout << "FN-2187";
FN-2187
const char whatever[] = "FN-2187"; cout << whatever;
FN-2187
const char whatever[] = "FN-2187"; const char *p = &whatever[0]; cout << p;
FN-2187
"string literal"
is like an anonymous array.
Sequence | Meaning | Sequence | Meaning |
---|---|---|---|
\a | bell | \' | ' |
\b | backspace | \" | " |
\f | form feed | \\ | \ |
\n | newline | \0 ddd | 0–3 octal digits |
\r | carriage return | \x dd | 1–∞ hex digits |
\t | horizontal tab | \u dddd | Unicode U+dddd |
\v | vertical tab | \U dddddddd | Unicode U+dddddddd |
Two adjacent string literals are merged into one at compile-time:
cout << "alpha beta " "gamma delta " "epsilon\n";
alpha beta gamma delta epsilon
cout << "Business plan:\n\n" "1. Collect underpants\n" "2. ?\n" "3. Profit\n";
Business plan: 1. Collect underpants 2. ? 3. Profit
A raw string starts with R"(
and ends with )"
.
The parens are not part of the string.
cout << R"(Don't be "afraid" of letters: \a\b\c\d\e\f\g)";
Don't be "afraid" of letters: \a\b\c\d\e\f\g
Cool! Quotes inside of quotes!
What if the string contains a right paren? I want to emit:
A goatee! :-)" Cool!
cout << "A goatee! :-)" Cool!";
c.cc:1: warning: missing terminating " character c.cc:1: error: missing terminating " character
That didn’t work. The )"
at the bottom of the face
was taken to be the end of the raw string.
A raw string starts with:
R"
whatever-you-like-up-to-sixteen-chars(
and ends with:
)
the-same-up-to-sixteen-chars"
cout << R"X(A goatee! :-)" Cool!)X";
A goatee! :-)" Cool!
cout << R"WashYourHair(What the #"%'&*)?)WashYourHair";
What the #"%'&*)?
cout << R"(The degenerate case)";
The degenerate case
if ("foo" < "bar") cout << "😢";
c.cc:1: warning: comparison with string literal results in unspecified behavior 😢
"marx"
and "marx"
two arrays or one? Who knows‽
g++ -Wall
will detect this deplorable code.
strcmp(a,b)
returns:
a
<b
.
a
==b
.
a
>b
.
std::string
sstd::string
values, or to compare a std::string
with a C-style string, use the usual operators:
< > <= >= == !=
std::string::compare()
,
which has the same three-way return value as strcmp.
string name = "Conan O’Brien"; if (name == "Conan O’Brien") cout << "good 1\n"; if (name < "Zulu") cout << "good 2\n"; if (name > "Andy Richter") cout << "good 3\n"; if (name == name) cout << "good 4\n";
good 1 good 2 good 3 good 4