string的用法集合

string的用法

3.2.标准库string类型

Thestringtype supportsvariable-length character strings. The library takes care of managingthe memory associated with storing the characters and providesvarious useful operations. The librarystringtype is intended to be efficient enough for general use.

string类型支持长度可变的字符串,C++标准库将负责管理与存储字符相关的内存,以及提供各种有用的操作。标准库string类型的目的就是满足对字符串的一般应用。

Aswith any library type, programs that usestringsmust first include the associated header. Our programs will beshorter if we also provide an appropriateusingdeclaration:

与其他的标准库类型一样,用户程序要使用string类型对象,必须包含相关头文件。如果提供了合适的using声明,那么编写出来的程序将会变得简短些:

#include <string>
     using std::string;

3.2.1.Defining and Initializingstrings

3.2.1.string对象的定义和初始化

Thestringlibrary provides several constructors (Section2.3.3, p.49).A constructor is a special member function that defines how objectsof that type can be initialized. Table 3.1 on the facing page liststhe most commonly usedstringconstructors. The default constructor (Section2.3.4, p.52)is used "by default" when no initializer is specified.

string标准库支持几个构造函数(2.3.3)。构造函数是一个特殊成员函数,定义如何初始化该类型的对象。3.1列出了几个string类型常用的构造函数。当没有明确指定对象初始化式时,系统将使用默认构造函数(2.3.4)。

Table3.1. Ways to Initialize astring
3.1.几种初始化string对象的方式
**strings1;** **Defaultconstructor; s1 is the empty string**
**默认构造函数****s1****为空串**
**strings2(s1);** **Initializes2 as a copy of s1**
**将****s2****初始化为****s1****的一个副本**
**strings3("value");** **Initializes3 as a copy of the string literal**
**将****s3****初始化为一个字符串字面值副本**
**strings4(n, 'c');** **Initializes4 with n copies of the character 'c'**
**将****s4****初始化为字符****'c'****的****n****个副本**



## **Caution:Library****string****Type andString Literals**

## **警告:标准库****string****类型和字符串字面值**

**Forhistorical reasons, and for compatibility with C, character stringliterals are not the same type as the standard library****string****type. This fact can cause confusion and is important to keep inmind when using a string literal or the****string****data type.**

**因为历史原因以及为了与****C****语言兼容,字符串字面值与标准库****string****类型不是同一种类型。这一点很容易引起混乱,编程时一定要注意区分字符串字面值和****string****数据类型的使用,这很重要。**



## **ExercisesSection 3.2.1**

**Exercise3.2:** **Whatis a default constructor?**

**什么是默认构造函数?**

**Exercise3.3:****Namethe three ways to initialize a****string****.**

**列举出三种初始化****string****对象的方法。**

**Exercise3.4:****Whatare the values of****s****and****s2****?**

**s****和****s2****的值分别是什么?**

string s;
     int main() {
      string s2;
     }





3.2.2.Reading and Writingstrings

3.2.2.string对象的读写

我们已在第一章学习了用iostream标准库来读写内置类型的值,如intdouble等。同样地,也可以用iostreamstring标准库,使用标准输入输出操作符来读写string对象:

// Note: #include and using declarations must be added to compile this code
     int main()
     {
         string s;          // empty string
         cin >> s;          // read whitespace-separated string into s
         cout << s << endl; // write s to the output
         return 0;
     }

Thisprogram begins by defining astringnameds. The next line,

以上程序首先定义命名为sstring第二行代码:

cin >> s;        // read whitespace-separated string into s

reads thestandard input storing what is read intos.Thestringinput operator:

从标准输入读取string并将读入的串存储在s中。string类型的输入操作符:

  • Readsand discards any leading whitespace (e.g., spaces, newlines, tabs)

读取并忽略开头所有的空白字符(如空格,换行符,制表符)。

  • Itthen reads characters until the next whitespace character isencountered

读取字符直至再次遇到空白字符,读取终止。

So, if theinput to this program is "HelloWorld!", (note leading and trailing spaces) then theoutput will be "Hello"with no extra spaces.

如果给定和上一个程序同样的输入,则输出的结果是"HelloWorld!"(注意到开头和结尾的空格),则屏幕上将输出"Hello",而不含任何空格。

Theinput and output operations behave similarly to the operators on thebuiltin types. In particular, the operators return their left-handoperand as their result. Thus, we can chain together multiple readsor writes:

输入和输出操作的行为与内置类型操作符基本类似。尤其是,这些操作符返回左操作数作为运算结果。因此,我们可以把多个读操作或多个写操作放在一起:

string s1, s2;
     cin >> s1 >> s2; // read first input into s1, second into s2
     cout << s1 << s2 << endl; // write both strings

If we givethis version of the program the same input as in the previousparagraph, our output would be

如果给定和上一个程序同样的输入,则输出的结果将是:

HelloWorld!
![](http://www.9wy.net/onlinebook/CPlusPlusPrimer/images/0201721481/graphics/beware.jpg;400478) **Tocompile this program, you must add****#include****directives for both the****iostream****and****string****libraries andmust issue****using****declarations for all the names used from the library:****string,cin, cout****, and****endl****.**

**对于上例,编译时必须加上****#include****来标示****iostream****和****string****标准库,以及给出用到的所有标准库中的名字(如****string****,****cin****,****cout****,****endl****)的****using****声明。**

Theprograms presented from this point on will assume that the needed#includeandusingdeclarations have been made.

从本例开始的程序均假设程序中所有必须#includeusing声明已给出。

Readingan Unknown Number ofstrings
读入未知数目的string对象

Likethe input operators that read built-in types, thestringinput operator returns the stream from which it read. Therefore, wecan use astringinputoperation as a condition, just as we did when readingintsin the program on page 18. The following program reads a set ofstrings from the standardinput and writes what it has read, onestringper line, to the standard output:

和内置类型的输入操作一样,string的输入操作符也会返回所读的数据流。因此,可以把输入操作作为判断条件,这与我们在1.4.4节读取整型数据的程序做法是一样的。下面的程序将从标准输入读取一组string对象,然后在标准输出上逐行输出:

int main()
     {
         string word;
         // read until end-of-file, writing each word to a new line
         while (cin >> word)
             cout << word << endl;
         return 0;
     }

In thiscase, we read into astringusing the input operator. That operator returns theistreamfrom which it read, and thewhilecondition tests the stream after the read completes. If the stream isvalidit hasn't hit end-of-file or encountered an invalid inputthenthe body of thewhileisexecuted and the value we read is printed to the standard output.Once we hit end-of-file, we fall out of thewhile.

上例中,用输入操作符来读取string对象。该操作符返回所读的istream对象,并在读取结束后,作为while的判断条件。如果输入流是有效的,即还未到达文件尾且未遇到无效输入,则执行while循环体,并将读取到的字符串输出到标准输出。如果到达了文件尾,则跳出while循环。

Usinggetlineto Read an Entire Line
使用getline读取整行文本

There is anadditional usefulstringIOoperation:getline.This is a function that takes both an input stream and astring.Thegetlinefunction reads thenext line of input from the stream and stores what it read, notincluding the newline, in its string argument. Unlike the inputoperator,getlinedoes notignore leading newlines. Whenevergetlineencounters a newline, even if it is the first character in the input,it stops reading the input and returns. The effect of encountering anewline as the first character in the input is that thestringargument is set to the emptystring.

另外还有一个有用的stringIO操作:getline。这个函数接受两个参数:一个输入流对象和一个string对象。getline函数从输入流的下一行读取,并保存读取的内容到不包括换行符。和输入操作符不一样的是,getline并不忽略行开头的换行符。只要getline遇到换行符,即便它是输入的第一个字符,getline也将停止读入并返回。如果第一个字符就是换行符,则string参数将被置为空string

Thegetlinefunction returns itsistreamargument so that, likethe input operator, it can be used as a condition. For example, wecould rewrite the previous program that wrote one word per line towrite a line at a time instead:

getline函数将istream参数作为返回值,和输入操作符一样也把它用作判断条件。例如,重写前面那段程序,把每行输出一个单词改为每次输出一行文本:

int main()
     {
         string line;
         // read line at time until end-of-file
         while (getline(cin, line))
             cout << line << endl;
         return 0;
     }

Becauselinedoes not contain anewline, we must write our own if we want thestringswritten one to a line. As usual, we useendlto write a newline and flush the output buffer.

由于line不含换行符,若要逐行输出需要自行添加。照常,我们用endl来输出一个换行符并刷新输出缓冲区。

string的用法集合 Thenewline that causesgetlineto return is discarded; it does not get stored in thestring.

由于getline函数返回时丢弃换行符,换行符将不会存储在string对象中。



## **ExercisesSection 3.2.2**

**Exercise3.5:** **Writea program to read the standard input a line at a time. Modifyyour program to read a word at a time.**

**编写程序实现从标准输入每次读入一行文本。然后改写程序,每次读入一个单词。**

**Exercise3.6:****Explainhow whitespace characters are handled in the****string****input operator and in the****getline****function.**

**解释****string****类型的输入操作符和****getline****函数分别如何处理空白字符。**



3.2.3.Operations onstrings

3.2.3.string对象的操作

Table3.2on the next page lists the mostcommonly usedstringoperations.

3.2列出了常用的string操作。

Table3.2.stringOperations
**s.empty()** **Returnstrue if s is empty; otherwise returns false**

**如果****s****为空串,则返回****true****,否则返回****false****。**

**s.size()****Returnsnumber of characters in s**

**返回****s****中字符的个数**

**s[n]****Returnsthe character at position n in s; positions start at 0.**

**返回****s****中位置为****n****的字符,位置从****0****开始计数**

**s1+ s2****Returnsa string equal to the concatenation of s1 and s2**

**把****s1****和****s2****连接成一个新字符串,返回新生成的字符串**

**s1= s2****Replacescharacters in s1 by a copy of s2**

**把****s1****内容替换为****s2****的副本**

**v1== v2****Returnstrue if v1 and v2 are equal; false otherwise**

**比较****v1****与****v2****的内容,相等则返回****true****,否则返回****false**

**!=,<, <=, >, and >=****Havetheir normal meanings**

**保持这些操作符惯有的含义**

Thestring size and empty Operations
stringsizeempty操作

Thelength of astringis thenumber of characters in thestring.It is returned by thesizeoperation:

string对象的长度指的是string对象中字符的个数,可以通过size操作获取:

int main()
     {
         string st("The expense of spirit\n");
         cout << "The size of " << st << "is " << st.size()
              << " characters, including the newline" << endl;
         return 0;
     }

If wecompile and execute this program it yields

编译并运行这个程序,得到的结果为:

The size of The expense of spirit
     is 22 characters, including the newline

Often it isuseful to know whether astringis empty. One way we could do so would be to comparesizewith 0:

了解string对象是否空是有用的。一种方法是将size0进行比较:

if (st.size() == 0)
          // ok: empty

In thiscase, we don't really need to know how many characters are in thestring; we are only interestedin whether thesizeis zero.We can more directly answer this question by using theemptymember:

本例中,程序员并不需要知道string对象中有多少个字符,只想知道size是否为0。用string的成员函数empty()可以更直接地回答这个问题:

if (st.empty())
          // ok: empty

Theemptyfunction returns thebool(Section2.1, p.34)valuetrueif thestringcontains no characters; otherwise, it returnsfalse.

empty()成员函数将返回bool2.1),如果string对象为空则返回true否则返回false

string::size_type
string::size_type类型

Itmight be logical to expect thatsizereturns anint, or, thinkingback to the note on page38,anunsigned. Instead, thesizeoperation returns a value of typestring::size_type.This type requires a bit of explanation.

从逻辑上来讲,size()成员函数似乎应该返回整形数值,或如2.2建议中所述的无符号整数。但事实上,size操作返回的是string::size_type类型的值。我们需要对这种类型做一些解释。

Thestringclassand many other library typesdefines several companion types.These companion types make it possible to use the library types in amachine-independent manner. The typesize_typeis one of these companion types. It is defined as a synonym for anunsignedtypeeitherunsignedintorunsigned longthatis guaranteed to be big enough to hold the size of anystring.To use thesize_typedefinedbystring, we use the scopeoperator to say that the namesize_typeis defined in thestringclass.

string类类型和许多其他库类型都定义了一些配套类型(companiontype)。通过这些配套类型,库类型的使用就能与机器无关(machine-independent)。size_type就是这些配套类型中的一种。它定义为与unsigned型(unsignedintunsignedlong)具有相同的含义,而且可以保证足够大能够存储任意string对象的长度。为了使用由string类型定义的size_type类型是由string类定义。

string的用法集合 Anyvariable used to store the result from thestringsizeoperation ought to be of typestring::size_type.It is particularly important not to assign the return fromsizeto anint.

任何存储stringsize操作结果的变量必须为string::size_type类型。特别重要的是,还要把size的返回值赋给一个int变量。

Althoughwe don't know the precise type ofstring::size_type,wedo know that it is anunsignedtype (Section2.1.1, p.34).We also know that for a given type, theunsignedversion can hold a positive value twice as large as the correspondingsignedtype can hold. Thisfact implies that the largeststringcould be twice as large as the size anintcan hold.

虽然我们不知道string::size_type的确切类型,但可以知道它是unsigned型(2.1.1)。对于任意一种给定的数据类型,它的unsigned型所能表示的最大正数值比对应的signed型要大倍。这个事实表明size_type存储的string长度是int所能存储的两倍。

Anotherproblem with using anintisthat on some machines the size of anintis too small to hold the size of even plausibly largestrings.For example, if a machine has 16-bitints,then the largeststringanintcould represent would have 32,767 characters. Astringthat held the contents of a file could easily exceed this size. Thesafest way to hold thesizeofastringis to use the typethe library defines for this purpose, which isstring::size_type.

使用int变量的另一个问题是,有些机器上int变量的表示范围太小,甚至无法存储实际并不长的string对象。如在有16int型的机器上,int类型变量最大只能表示32767个字符的string个字符的string对象。而能容纳一个文件内容的string对象轻易就会超过这个数字。因此,为了避免溢出,保存一个stirng对象size的最安全的方法就是使用标准库类型string::size_type

ThestringRelational Operators
string关系操作符

Thestringclass defines severaloperators that compare twostringvalues. Each of these operators works by comparing the charactersfrom eachstring.

string类定义了几种关系操作符用来比较两个string值的大小。这些操作符实际上是比较每个string

string的用法集合 stringcomparisons are case-sensitivethe upper- and lowercase versions ofa letter are different characters. On most computers, theuppercase letters come first: Every uppercase letter is less thanany lowercase letter.

string对象比较操作是区分大小写的,即同一个字符的大小写形式被认为是两个不同的字符。在多数计算机上,大写的字母位于小写之前:任何一个大写之母都小于任意的小写字母。

Theequality operator compares twostrings,returningtrueif they areequal. Twostrings are equalif they are the same length and contain the same characters. Thelibrary also defines!=totest whether twostrings areunequal.

==操作符比较两个string对象,如果它们相等,则返回true。两个string对象相等是指它们的长度相同,且含有相同的字符。标准库还定义了!=操作符来测试两个string对象是否不等。

Therelational operators<, <=, >, >=test whether onestringisless than, less than or equal, greater than, or greater than or equalto another:

关系操作符<<=>>=分别用于测试一个string对象是否小于、小于或等于、大于、大于或等于另一个string对象:

string big = "big", small = "small";
     string s1 = big;    // s1 is a copy of big
     if (big == small)   // false
         // ...
     if (big <= s1)      // true, they're equal, so big is less than or equal to s1
         // ...

Therelational operators comparestringsusing the same strategy as in a (case-sensitive) dictionary:

关系操作符比较两个string对象时采用了和(大小写敏感的)字典排序相同的策略:

  • Iftwostrings have differentlengths and if every character in the shorterstringis equal to the corresponding character of the longerstring,then the shorterstringisless than the longer one.

  • 如果两个string对象长度不同,且短的string对象与长的string对象的前面部分相匹配,则短的string对象小于长的string对象。

  • Ifthe characters in twostringsdiffer, then we compare them by comparing the first character atwhich thestrings differ.

  • 如果string对象的字符不同,则比较第一个不匹配的字符。string

As anexample, given thestrings

举例来说,给定string对象;

string substr = "Hello";
     string phrase = "Hello World";
     string slang  = "Hiya";

thensubstris less thanphrase, andslangis greater than eithersubstrorphrase.

substr小于phrase,而slang则大于substrphrase

Assignmentforstrings
string对象的赋值

Ingeneral the library types strive to make it as easy to use a librarytype as it is to use a built-in type. To this end, most of thelibrary types support assignment. In the case ofstrings,we can assign onestringobject to another:

总体上说,标准库类型尽量设计得和基本数据类型一样方便易用。因此,大多数库类型支持赋值操作。对string对象来说,可以把一个string对象赋值给另一个string对象;

// st1 is an empty string, st2 is a copy of the literal
     string st1, st2 = "The expense of spirit";
     st1 = st2; // replace st1 by a copy of st2

After theassignment,st1contains acopy of the characters inst2.

赋值操作后,st1就包含了st2串所有字符的一个副本。

Moststringlibrary implementationsgo to some trouble to provide efficient implementations of operationssuch as assignment, but it is worth noting that conceptually,assignment requires a fair bit of work. It must delete the storagecontaining the characters associated withst1,allocate the storage needed to contain a copy of the charactersassociated withst2, and thencopy those characters fromst2into this new storage.

大多数string库类型的赋值等操作的实现都会遇到一些效率上的问题,但值得注意的是,从概念上讲,赋值操作确实需要做一些工作。它必须先把st1占用的相关内存释放掉,然后再分配给st2足够存放st2副本的内存空间,最后把st2中的所有字符复制到新分配的内存空间。

AddingTwostrings
两个string对象相加

Additiononstrings is defined asconcatenation. That is, it is possible to concatenate two or morestrings through the use ofeither the plus operator (+)or the compound assignment operator (+=)(Section1.4.1, p.13).Given the twostrings

string对象的加法被定义为连接(concatenation)。也就是说,两个(或多个)string对象可以通过使用加操作符+或者复合赋值操作符+=1.4.1)连接起来。给定两个string对象:

string s1("hello, ");
     string s2("world\n");

we canconcatenate the twostrings tocreate a thirdstringasfollows:

下面把两个string对象连接起来产生第三个string对象:

string s3 = s1 + s2;   // s3 is hello, world\n

If wewanted to appends2tos1directly, then we would use+=:

如果要把s2直接追加到s1的末尾,可以使用+=操作符:

s1 += s2;   // equivalent to s1 = s1 + s2
AddingCharacter String Literals andstrings
和字符串字面值的连接

Thestringss1ands2included punctuationdirectly. We could achieve the same result by mixingstringobjects and string literals as follows:

上面的字符串对象s1s2直接包含了标点符号。也可以通过将string对象和字符串字面值混合连接得到同样的结果:

string s1("hello");
     string s2("world");

     string s3 = s1 + ", " + s2 + "\n";

When mixingstrings and string literals,at least one operand to each+operator must be ofstringtype:

当进行string对象和字符串字面值混合连接操作时,+操作符的左右操作数必须至少有一个是string类型的:

string s1 = "hello";   // no punctuation
     string s2 = "world";
     string s3 = s1 + ", ";           // ok: adding a string and a literal
     string s4 = "hello" + ", ";      // error: no string operand
     string s5 = s1 + ", " + "world"; // ok: each + has string operand
     string s6 = "hello" + ", " + s2; // error: can't add string literals

Theinitializations ofs3ands4involve only a single operation. In these cases, it is easy todetermine that the initialization ofs3is legal: We initializes3byadding astringand a stringliteral. The initialization ofs4attempts to add two string literals and is illegal.

s3s4的初始化只用了一个单独的操作。在这些例子中,很容易判断s3的初始化是合法的:把一个string对象和一个字符串字面值连接起来。而s4的初始化试图将两个字符串字面值相加,因此是非法的。

Theinitialization ofs5mayappear surprising, but it works in much the same way as when we chaintogether input or output expressions (Section1.2, p.5).In this case, thestringlibrary defines addition to return astring.Thus, when we initializes5,the subexpressions1 + ", "returns astring, which can beconcatenated with the literal"world\n".It is as if we had written

s5的初始化方法显得有点不可思议,但这种用法和标准输入输出的串联效果是一样的(1.2)。本例中,string标准库定义加操作返回一个string对象。这样,在对s5进行初始化时,子表达式s1+ ", "将返回一个新string对象,后者再和字面值"world\n"连接。整个初始化过程可以改写为:

string tmp = s1 + ", "; // ok: + has a string operand
     s5 = tmp + "world";     // ok: + has a string operand

On theother hand, the initialization ofs6is illegal. Looking at each subexpression in turn, we see that thefirst subexpression adds two string literals. There is no way to doso, and so the statement is in error.

s6的初始化是非法的。依次来看每个子表达式,则第一个子表达式试图把两个字符串字面值连接起来。这是不允许的,因此这个语句是错误的。

Fetchinga Character from astring
string对象获取字符

Thestringtype uses the subscript([ ]) operator to access theindividual characters in thestring.The subscript operator takes asize_typevalue that denotes the character position we wish to fetch. The valuein the subscript is often called "the subscript" or "anindex."

string类型通过下标操作符([])来访问string对象中的单个字符。下标操作符需要取一个size_type类型的值,来标明要访问字符的位置。这个下标中的值通常被称为下标索引index


string的用法集合 Subscriptsforstrings start at zero;ifsis astring,then ifsisn't empty,s[0]is the first character in thestring,s[1]is the second if there is one, and the lastcharacter is ins[s.size() - 1].

string对象的下标从0开始。如果s是一个string对象且s不空,则s[0]就是字符串的第一个字符,s[1]就表示第二个字符(如果有的话),而s[s.size()- 1]则表示s的最后一个字符。

Itis an error to use an index outside this range.

引用下标时如果超出下标作用范围就会引起溢出错误。

Wecould use the subscript operator to print each character in astringon a separate line:

可用下标操作符分别取出string对象的每个字符,分行输出:

string str("some string");
     for (string::size_type ix = 0; ix != str.size(); ++ix)
         cout << str[ix] << endl;

On eachtrip through the loop we fetch the next character fromstr,printing it followed by a newline.

每次通过循环,就从str对象中读取下一个字符,输出该字符并换行。

SubscriptingYields an Lvalue
下标操作可用作左值

Recall thata variable is an lvalue (Section2.3.1, p.45),and that the left-hand side of an assignment must be an lvalue. Likea variable, the value returned by the subscript operator is anlvalue. Hence, a subscript can be used on either side of anassignment. The following loop sets each character instrto an asterisk:

前面说过,变量是左值(2.3.1),且赋值操作的左操作的必须是左值。和变量一样,string对象的下标操作返回值也是左值。因此,下标操作可以放于赋值操作符的左边或右边。通过下面循环把str对象的每一个字符置为*:**

for (string::size_type ix = 0; ix != str.size(); ++ix)
         str[ix] = '*';
ComputingSubscript Values
计算下标值

Anyexpression that results in an integral value can be used as the indexto the subscript operator. For example, assumingsomevalandsomeothervalare integralobjects, we could write

任何可产生整型值的表达式可用作下标操作符的索引。例如,假设somevalsomeotherval是两个整形对象,可以这样写:

str[someotherval * someval] = someval;

Althoughany integral type can be used as an index, the actual type of theindex isstring::size_type,which is anunsignedtype.

虽然任何整型数值都可作为索引,但索引的实际数据类型却是类型unsigned类型string::size_type

string的用法集合 Thesame reasons to usestring::size_typeas the type for a variable that holds the return fromsizeapply when defining a variable to serve as an index. A variableused to index astringshould have typestring::size_type.

前面讲过,应该用string::size_type类型的变量接受size函数的返回值。在定义用作索引的变量时,出于同样的道理,string对象的索引变量最好也用string::size_type类型。

Whenwe subscript astring, we areresponsible for ensuring that the index is "in range." Byin range, we mean that the index is a number that, when assigned to asize_type, is a value in therange from 0 through the size of thestringminus one. By using astring::size_typeor anotherunsignedtype asthe index, we ensure that the subscript cannot be less than zero. Aslong as our index is anunsignedtype, we need only check that it is less than the size of thestring.

在使用下标索引string对象时,必须保证索引值在上下界范围内在上下界范围内就是指索引值是一个赋值为size_type类型的值,其取值范围在0string对象长度减1之间。使用string::size_type类型或其他unsigned类型,就只需要检测它是否小于string对象的长度。

string的用法集合 Thelibrary is not required to check the value of the index. Using anindex that is out of range is undefined and usually results in aserious run-time error.

标准库不要求检查索引值,所用索引的下标越界是没有定义的,这样往往会导致严重的运行时错误。

3.2.4.Dealing with the Characters of astring

3.2.4.string对象中字符的处理

Oftenwe want to process the individual characters of astring.For example, we might want to know if a particular character is awhitespace character or whether the character is alphabetic ornumeric.Table3.3on the facing page lists thefunctions that can be used on the characters in astring(or on any othercharvalue).These functions are defined in thecctypeheader.

我们经常要对string对象中的单个字符进行处理,例如,通常需要知道某个特殊字符是否为空白字符、字母或数字。3.3列出了各种字符操作函数,适用于string对象的字符(或其他任何char值)。这些函数都在cctype头文件中定义。

Table3.3.cctypeFunctions
**isalnum(c)** **Trueif c is a letter or a digit.**

**如果****c****是字母或数字,则为****True****。**

**isalpha(c)****trueif c is a letter.**

**如果****c****是字母,则为****true****。**

**iscntrl(c)****trueif c is a control character.**

**如果****c****是控制字符,则为****true**

**isdigit(c)****trueif c is a digit.**

**如果****c****是数字,则为****true****。**

**isgraph(c)****trueif c is not a space but is printable.**

**如果****c****不是空格,但可打印,则为****true****。**

**islower(c)****trueif c is a lowercase letter.**

**如果****c****是小写字母,则为****true****。**

**isprint(c)****Trueif c is a printable character.**

**如果****c****是可打印的字符,则为****true****。**

**ispunct(c)****Trueif c is a punctuation character.**

**如果****c****是标点符号,则****true****。**

**isspace(c)****trueif c is whitespace.**

**如果****c****是空白字符,则为****true****。**

**isupper(c)****Trueif c is an uppercase letter.**

**如果****c****是大写字母,则****true****。**

**isxdigit(c)****trueif c is a hexadecimal digit.**

**如果是****c****十六进制数,则为****true****。**

**tolower(c)****Ifc is an uppercase letter, returns its lowercase equivalent;otherwise returns c unchanged.**

**如果****c****大写字母,返回其小写字母形式,否则直接返回****c****。**

**toupper(c)****Ifc is a lowercase letter, returns its uppercase equivalent;otherwise returns c unchanged.**

**如果****c****是小写字母,则返回其大写字母形式,否则直接返回****c****。**

Thesefunctions mostly test the given character and return an int, whichacts as a truth value. Each function returns zero if the test fails;otherwise, they return a (meaningless) nonzero value indicating thatthe character is of the requested kind.

表中的大部分函数是测试一个给定的字符是否符合条件,并返回一个int作为真值。如果测试失败,则该函数返回0,否则返回一个(无意义的)非0,表示被测字符符合条件。

Forthese functions, a printable character is a character with a visiblerepresentation; whitespace is one of space, tab, vertical tab,return, newline, and formfeed; and punctuation is a printablecharacter that is not a digit, a letter, or (printable) whitespacecharacter such as space.

表中的这些函数,可打印的字符是指那些可以表示的字符,空白字符则是空格、制表符、垂直制表符、回车符、换行符和进纸符中的任意一种;标点符号则是除了数字、字母或(可打印的)空白字符(如空格)以外的其他可打印字符。

Asan example, we could use these functions to print the number ofpunctuation characters in a givenstring:

这里给出一个例子,运用这些函数输出一给定string对象中标点符号的个数:

string s("Hello World!!!");
     string::size_type punct_cnt = 0;
     // count number of punctuation characters in s
     for (string::size_type index = 0; index != s.size(); ++index)
         if (ispunct(s[index]))
             ++punct_cnt;
     cout << punct_cnt
          << " punctuation characters in " << s << endl;

The outputof this program is

这个程序的输出结果是:

3 punctuation characters in Hello World!!!

Rather thanreturning a truth value, thetolowerandtoupperfunctions return acharactereither the argument unchanged or the lower- or uppercaseversion of the character. We could usetolowerto changesto lowercase asfollows:

和返回真值的函数不同的是,tolowertoupper函数返回的是字符,返回实参字符本身或返回该字符相应的大小写字符。我们可以用tolower函数把string对象s中的字母改为小写字母,程序如下:

// convert s to lowercase
     for (string::size_type index = 0; index != s.size(); ++index)
         s[index] = tolower(s[index]);
     cout << s << endl;

whichgenerates

得到的结果为:

hello world!!!
## **Advice:Use the C++ Versions of C Library Headers**

## **建议:采用****C****标准库头文件的****C++****版本**

**Inaddition to facilities defined specifically for C++, the C++library incorporates the C library. The****cctype****header makes available the C library functions defined in the Cheader file named****ctype.h****.**

**C++****标准库除了定义了一些选定于****C++****的设施外,还包括****C****标准库。****C++****中的头文件****cctype****其实就是利用了****C****标准库函数,这些库函数就定义在****C****标准库的****ctype.h****头文件中。**

**Thestandard C headers names use the form name****.h****.The C++ versions of these headers are named****c****nametheC++ versions remove the****.h****suffix and precede the name by the letter****c****.The****c****indicates that theheader originally comes from the C library. Hence,****cctype****has the same contents as****ctype.h****,but in a form that is appropriate for C++ programs. In particular,the names defined in the****c****nameheaders are defined inside the****std****namespace, whereas those defined in the****.h****versions are not.**

**C****标准库头文件命名形式为****name****而****C++****版本则命名为****cname****,少了后缀,****.h****而在头文件名前加了****c****表示这个头文件源自****C****标准库。因此,****cctype****与****ctype.h****文件的内容是一样的,只是采用了更适合****C++****程序的形式。特别地,****cname****头文件中定义的名字都定义在命名空间****std****内,而****.h****版本中的名字却不是这样。**

**Ordinarily,C++ programs should use the****c****nameversions of headers and not the****name.h****versions. That way names from the standard library areconsistently found in the****std****namespace. Using the****.h****headers puts the burden on the programmer to remember whichlibrary names are inherited from C and which are unique to C++.**

**通常,****C++****程序中应采用****c****name****这种头文件的版本,而不采用****name.h****版本,这样,标准库中的名字在命名空间****std****中保持一致。使用****.h****版本会给程序员带来负担,因为他们必须记得哪些标准库名字是从****C****继承来的,而哪些是****C++****所特有的。**



## **ExercisesSection 3.2.4**

**Exercise3.7:** **Writea program to read two****string****sand report whether the****string****sare equal. If not, report which of the two is the larger. Now,change the program to report whether the****string****shave the same length and if not report which is longer.**

**编一个程序读入两个****string****对象,测试它们是否相等。若不相等,则指出两个中哪个较大。接着,改写程序测试它们的长度是否相等,若不相等指出哪个较长。**

**Exercise3.8:****Writea program to read****string****sfrom the standard input, concatenating what is read into onelarge****string****. Print theconcatenated****string****.Next, change the program to separate adjacent input****string****sby a space.**

**编一个程序,从标准输入读取多个****string****对象,把它们连接起来存放到一个更大的****string****对象中。并输出连接后的****string****对象。接着,改写程序,将连接后相邻****string****对象以空格隔开。**

**Exercise3.9:****Whatdoes the following program do? Is it valid? If not, why not?**

**下列程序实现什么功能?实现合法?如果不合法,说明理由。**

string s;
     cout << s[0] << endl;
**Exercise3.10:** **Writea program to strip the punctuation from a****string****.The input to the program should be a string of charactersincluding punctuation; the output should be a****string****in which the punctuation is removed.**

**编一个程序,从****string****对象中去掉标点符号。要求输入到程序的字符串必须含有标点符号,输出结果则是去掉标点符号后的****string****对象。**








原文链接: https://www.cnblogs.com/c-source/archive/2012/06/15/2564737.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/52823

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月9日 上午4:14
下一篇 2023年2月9日 上午4:14

相关推荐