Sei sulla pagina 1di 4

More Things about Strings

A string is a sequence of zero or more characters. The size function tells you h
ow many characters are in the string:
string s = "Hello";
cout << s.size(); // writes 5
s = "Wow";
cout << s.size(); // writes 3
s = "";
cout << s.size(); // writes 0
(For historical reasons, there is also a length function that returns the same v
alue that size does. In other words, s.length() and s.size() may be used interch
angeably.)
You can access individual characters in a string using the [] operator. The posi
tions of the characters in a string are numbered from left to right, starting at
0. Your program's behavior is undefined if it tries to access a character at a
position that is out of range for the string.
string s = "Hello";
cout << s[0];
//
cout << s[4];
//
cout << s[5];
//
cout << s[-1];
//

// 01234
// Hello
writes H
writes o
Undefined behavior!
Undefined behavior!

To visit every character in a string (for example, to write each character of th


e string on a line by itself), you can say
string s = "Hello";
for (int k = 0; k != s.size(); k++)
cout << s[k] << endl;
While this will work for everything you're doing in this class, technically the
expression s.size() returns a number of a special type defined in the library: n
ot int, but string::size_type. This type name is a synonym for some unsigned int
eger type. (An unsigned integer variable can contain only whole numbers, no nega
tives.) It turns out that a consequence of the C++ expression rules is that if k
is an int, the loop above might not work correctly for strings over 2 billion c
haracters long, and the compiler might give you a warning about that, phrased as
a "signed/unsigned mismatch" or a "comparison between signed and unsigned integ
er expressions". Since we won't be using such ridiculously long strings, declari
ng k to be an int is fine.
Still, it's good practice to try to get a clean build with no warnings. Like the
boy who cried wolf, if the compiler gives you many warnings about things that a
re harmless, you won't notice the warnings you should take seriously. To elimina
te the warning you might get, you should declare k to be of the technically prop
er type:
for (string::size_type k = 0; k != text.size(); k++)
Most C++ library implementations make size_t synonymous with string::size_type,
so you can get away with the somewhat shorter
for (size_t k = 0; k != text.size(); k++)
Again, you don't have to do this; you can declare k to be an int if you like, bu

t in that case be prepared for possible (harmless) signed/unsigned warnings.


If you do choose to declare k to be of type string::size_type or size_t, you nee
d to be sure that you never try to make k negative. For example, if you try to t
raverse a string backward, then your saying
for (string::size_type k = text.size()-1; k >= 0; k--)
{
... text[k] ...
}
would lead to undefined behavior. (If an unsigned integer k is 0 when you execut
e k--, it will end up with a huge positive value. An unsigned integer is always
>= 0, so we execute the loop body and try to talk about a character at a positio
n way past the end of the string.) One correct way to write the loop is
string::size_type k = text.size();
while (k > 0)
{
k--;
... text[k] ...
}
Again, if we choose to make k an int, the for loop version would be fine, but we
'd get the (harmless) signed/unsigned warning.
Another thing you can do with a string is to append characters to the end of the
string. The += operator lets you do this. (This is a different use of the opera
tor than the one that lets you add a number to an int or double variable.) Here'
s an example where we copy all of the non-blank characters from the string s to
the string t:
string s = "Hello there! How are you?";
string t; // automatically initialized to the empty string
for (size_t k = 0; k != s.size(); k++)
{
if (s[k] != ' ') // If s[k] is not a blank
t += s[k];
// append s[k] to t
}
cout << t; // writes Hellothere!Howareyou?
Notice that when talking about constants representing single characters, we use
single quote marks, not double quote marks. C++ distinguishes between the type s
tring, objects of which are sequences of zero or more characters, and the type c
har, objects of which are always a single character. If s is a string, then the
expression s[k] is a char. The language lets us compare a char with another char
, like the constants ' ' or '@' or 'A'. (The single quotes denote a char constan
t.)
You are also able to copy a substring of a string. For example, here's how we ca
n copy the substring of s starting at position 5 and going for 3 characters:
string s = "duplicate";
cout << s.substr(5,3);

// 012345678
// duplicate
// writes cat

Here's how to clip off the first six characters of a string:


string t = "fingernail";
t = t.substr(6, t.size()-6); // t is now "nail"

Sometimes we want to classify characters, asking, for example, whether they are
letter characters or digit characters. If you say
#include <cctype>
then you can use character classification functions like these:
string s = "Maroon
if (isalpha(s[0]))
...
if (isupper(s[0]))
...
if (islower(s[2]))
...
if (isdigit(s[7]))
...
if (islower(s[0]))
...
if (isalpha(s[6]))
...
if (isalpha(s[7]))
...

// 01234567
5"; // Maroon 5
// true, since 'M' is a letter
// true, since 'M' is an uppercase letter
// true, since 'r' is a lowercase letter
// true, since '5' is a digit character
// false, since 'M' is not a lowercase letter
// false, since ' ' is not a letter
// false, since '5' is not a letter

This code copies all non-letters in a string:


string s = "#1 in 2014:
string t;
for (size_t k = 0; k !=
if (!isalpha(s[k]))
t += s[k];

Yeah!";
s.size(); k++)
// if not a letter
// append it to t

// t is now "#1 2014: !"


The function tolower, when given an uppercase letter, returns the lowercase equi
valent of that letter; when given any other character, just returns that same ch
aracter. So
string s = "Don't SHOUT!";
string t;
for (size_t k = 0; k != s.size(); k++)
t += tolower(s[k]);
cout << t;
writes don't shout!. Similarly, the function toupper returns the uppercase equiv
alent of a letter.
There's a lot more you can do with strings and characters, but the information i
n this tutorial will suffice to enable you to do Project 3.
=====Visual C++: s[k] when k is out of range=====
We've seen that we can access the character of a string s at position k:
string s = "Hello";
cout << s[0];
// writes H
cout << s[4];
// writes o
If k is an integer such that k >= 0 and k < s.size(), then s[k] refers to the ch
aracter at position k of the string s. But what if k < 0 or k >= s.size()? The C

++ Standard says that s[k] in this case has undefined behavior: The program migh
t crash, or access memory that is not part of the string, or appear to work norm
ally, or appear to work for a while and then misbehave, or print a useful diagno
stic message, etc. Different compilers might do different things at different ti
mes.
When you build a Visual C++ project in the Debug configuration, which is what we
're doing, the Visual C++ 2012 library's implementation of the [] operator for s
trings will, in fact, check to see if the position is within range, and if not,
immediately terminate the program, putting up a dialog box containing the text D
ebug Assertion Failed! and string subscript out of range. This alone is useful i
n that it alerts you to a problem, but the real payoff comes if you know somethi
ng about using the Visual C++ 2012 debugger.
If your program uses the [] operator for strings and dies when run under Visual
C++ 2012, producing the dialog box with the message string subscript out of rang
e, you can click Retry to fire up the debugger. (Annoyingly, after clicking Retr
y, you will have to select "Debug the program" in the next dialog box that comes
up, and then in the next box, select the Possible Debugger that has the name of
your project, and click Yes. In the next dialog box that appears, click Break.)
In the Call Stack window, double-click the line just below the one containing "
yourProject.exe!std::basic_string<char,...". You'll then see your program code,
with an arrow in the left margin pointing to one of the lines of code. Somewhere
in the indicated line in your program code is your bad subscript; you can exami
ne the Autos window to see the values of any variables involved. Select Debug /
Stop Debugging when you're finished exploring.

Potrebbero piacerti anche