Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
B.Eckel - Thinking in C++, Vol.2, 2nd edition.pdf
Скачиваний:
50
Добавлен:
08.05.2013
Размер:
2.09 Mб
Скачать

requireArgs(argc, 1,

"usage: HTMLStripper InputFile"); ifstream in(argv[1]);

assure(in, argv[1]); const int sz = 4096; char buf[sz];

while(in.getline(buf, sz)) { string s(buf);

cout << stripHTMLTags(s) << endl;

}

} ///:~

The string class can replace one string with another but there’s no facility for replacing all the strings of one type with another, so the replaceAll( ) function does this for you, inside a while loop that keeps finding the next instance of the find string f. That function is used inside stripHTMLTags after it uses erase( ) to remove everything that appears inside angle braces (‘<‘ and ‘>‘). Note that I probably haven’t gotten all the necessary replacement values, but you can see what to do (you might even put all the find-replace pairs in a table…). In main( ) the arguments are checked, and the file is read and converted. It is sent to standard output so you must redirect it with ‘>‘ if you want to write it to a file.

Comparing strings

Comparing strings is inherently different than comparing numbers. Numbers have constant, universally meaningful values. To evaluate the relationship between the magnitude of two strings, you must make a lexical comparison. Lexical comparison means that when you test a character to see if it is “greater than” or “less than” another character, you are actually comparing the numeric representation of those characters as specified in the collating sequence of the character set being used. Most often, this will be the ASCII collating sequence, which assigns the printable characters for the English language numbers in the range from 32 to 127 decimal. In the ASCII collating sequence, the first “character” in the list is the space, followed by several common punctuation marks, and then uppercase and lowercase letters. With respect to the alphabet, this means that the letters nearer the front have lower ASCII values than those nearer the end. With these details in mind, it becomes easier to remember that when a lexical comparison that reports s1 is “greater than” s2, it simply means that when the two were compared, the first differing character in s1 came later in the alphabet than the character in that same position in s2.

C++ provides several ways to compare strings, and each has their advantages. The simplest to use are the non member overloaded operator functions operator ==, operator != operator >, operator <, operator >=, and operator <=.

//: C01:CompStr.cpp #include <string> #include <iostream>

Chapter 14: Templates & Container Classes

49

using namespace std;

int main() {

// Strings to compare string s1("This "); string s2("That ");

for(int i = 0; i< s1.size() && i < s2.size(); i++)

// See if the string elements are the same: if(s1[i] == s2[i])

cout << s1[i] << " " << i << endl; // Use the string inequality operators if(s1 != s2) {

cout << "Strings aren't the same:" << " "; if(s1 > s2)

cout << "s1 is > s2" << endl; else

cout << "s2 is > s1" << endl;

}

} ///:~

Here’s the output from CompStr.cpp:

T 0

h1

4

Strings aren’t the same: s1 is > s2

The overloaded comparison operators are useful for comparing both full strings and individual string elements.

Notice in the code fragment below the flexibility of argument types on both the left and right hand side of the comparison operators. The overloaded operator set allows the direct comparison of string objects, quoted literals, and pointers to C style strings.

//The lvalue is a quoted literal and

//the rvalue is a string

if("That " == s2)

cout << "A match" << endl;

//The lvalue is a string and the rvalue is a

//pointer to a c style null terminated string if(s1 != s2.c_str())

cout << "No match" << endl;

You won’t find the logical not (!) or the logical comparison operators (&& and ||) among operators for string. (Neither will you find overloaded versions of the bitwise C operators &, |,

Chapter 14: Templates & Container Classes

50

^, or ~.) The overloaded non member comparison operators for the string class are limited to the subset which has clear, unambiguous application to single characters or groups of characters.

The compare( ) member function offers you a great deal more sophisticated and precise comparison than the non member operator set, because it returns a lexical comparison value, and provides for comparisons that consider subsets of the string data. It provides overloaded versions that allow you to compare two complete strings, part of either string to a complete string, and subsets of two strings. This example compares complete strings:

//: C01:Compare.cpp

// Demonstrates compare(), swap() #include <string>

#include <iostream> using namespace std;

int main() {

string first("This"); string second("That");

// Which is lexically greater? switch(first.compare(second)) {

case 0: // The same

cout << first << " and " << second << " are lexically equal" << endl;

break;

case -1: // Less than first.swap(second);

// Fall through this case...

case 1: // Greater than cout << first <<

" is lexically greater than " << second << endl;

}

} ///:~

The output from Compare.cpp looks like this:

This is lexically greater than That

To compare a subset of the characters in one or both strings, you add arguments that define where to start the comparison and how many characters to consider. For example, we can use the overloaded version of compare( ):

s1.compare(s1StartPos, s1NumberChars, s2, s2StartPos, s2NumberChars);

If we substitute the above version of compare( ) in the previous program so that it only looks at the first two characters of each string, the program becomes:

Chapter 14: Templates & Container Classes

51

//: C01:Compare2.cpp

// Overloaded compare() #include <string> #include <iostream> using namespace std;

int main() {

string first("This"); string second("That");

// Compare first two characters of each string: switch(first.compare(0, 2, second, 0, 2)) {

case 0: // The same

cout << first << " and " << second << " are lexically equal" << endl;

break;

case -1: // Less than first.swap(second);

// Fall through this case...

case 1: // Greater than cout << first <<

" is lexically greater than " << second << endl;

}

} ///:~

The output is:

This and That are lexically equal

which is true, for the first two characters of “This” and “That.”

Indexing with [ ] vs. at( )

In the examples so far, we have used C style array indexing syntax to refer to an individual character in a string. C++ strings provide an alternative to the s[n] notation: the at( ) member. These two idioms produce the same result in C++ if all goes well:

//: C01:StringIndexing.cpp #include <string>

#include <iostream> using namespace std; int main(){

string s("1234"); cout << s[1] << " ";

cout << s.at(1) << endl; } ///:~

Chapter 14: Templates & Container Classes

52

Соседние файлы в предмете Численные методы
  • #
    08.05.20133.99 Mб22A.Menezes, P.van Oorschot,S.Vanstone - HANDBOOK OF APPLIED CRYPTOGRAPHY.djvu
  • #
  • #
    08.05.20135.91 Mб24B.Eckel - Thinking in Java, 3rd edition (beta).pdf
  • #
  • #
    08.05.20136.09 Mб17D.MacKay - Information Theory, Inference, and Learning Algorithms.djvu
  • #
    08.05.20133.85 Mб15DIGITAL Visual Fortran ver.5.0 - Programmers Guide to Fortran.djvu
  • #
    08.05.20131.84 Mб12E.A.Lee, P.Varaiya - Structure and Interpretation of Signals and Systems.djvu