string的用法
3.2.標准庫 string 類型
Thestring type 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:Librarystring Type andString Literals警告:標准庫 string 類型和字符串字面值Forhistorical reasons, and for compatibility with C, character stringliterals are not the same type as the standard librarystringtype. This fact can cause confusion and is important to keep inmind when using a string literal or thestringdata type. 因為歷史原因以及為了與 C 語言兼容,字符串字面值與標准庫 string 類型不是同一種類型。這一點很容易引起混亂,編程時一定要注意區分字符串字面值和 string 數據類型的使用,這很重要。 |
ExercisesSection 3.2.1 |
3.2.2.Reading and Writingstrings
3.2.2.string 對象的讀寫
我們已在第一章學習了用 iostream 標准庫來讀寫內置類型的值,如 int double 等。同樣地,也可以用 iostream 和 string 標准庫,使用標准輸入輸出操作符來讀寫 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 astringnamed s. The next line,
以上程序首先定義命名為 s 的 string 第二行代碼:
cin >> s; // read whitespace-separated string into s
reads thestandard input storing what is read intos.The string input 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!
![]() |
Tocompile this program, you must add#includedirectives for both theiostreamand string libraries andmust issueusingdeclarations 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#include andusingdeclarations have been made.
從本例開始的程序均假設程序中所有必須 #include 和 using 聲明已給出。
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 astring inputoperation 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 thewhile isexecuted 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 循環。
Usinggetline to Read an Entire Line
使用 getline 讀取整行文本
There is anadditional useful string IOoperation:getline.This is a function that takes both an input stream and astring.The getline function reads thenext line of input from the stream and stores what it read, notincluding the newline, in its string argument. Unlike the inputoperator, getline does 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.
另外還有一個有用的 string IO 操作:getline。這個函數接受兩個參數:一個輸入流對象和一個 string 對象。getline 函數從輸入流的下一行讀取,並保存讀取的內容到不包括換行符。和輸入操作符不一樣的是,getline 並不忽略行開頭的換行符。只要 getline 遇到換行符,即便它是輸入的第一個字符,getline 也將停止讀入並返回。如果第一個字符就是換行符,則 string 參數將被置為空 string。
Thegetline function returns itsistream argument 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; }
Becauseline does 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 來輸出一個換行符並刷新輸出緩沖區。
![]() |
Thenewline that causesgetlineto return is discarded; it does not get stored in thestring. 由於 getline 函數返回時丟棄換行符,換行符將不會存儲在 string 對象中。 |
ExercisesSection 3.2.2
|
3.2.3.Operations onstrings
3.2.3.string 對象的操作
Table3.2 on the next page lists the mostcommonly used stringoperations.
表3.2 列出了常用的 string 操作。
Table3.2.string Operations
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
string 的 size 和 empty 操作
Thelength of astring is 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 對象是否空是有用的。一種方法是將 size 與 0 進行比較:
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 the size is 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)valuetrue if the stringcontains no characters; otherwise, it returnsfalse.
empty() 成員函數將返回 bool(2.1 節),如果 string 對象為空則返回 true 否則返回 false。
string::size_type
string::size_type 類型
Itmight be logical to expect thatsizereturns an int, 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 anunsigned typeeitherunsignedint or unsigned longthatis guaranteed to be big enough to hold the size of anystring.To use the size_type definedby string, we use the scopeoperator to say that the namesize_typeis defined in thestringclass.
string 類類型和許多其他庫類型都定義了一些配套類型(companiontype)。通過這些配套類型,庫類型的使用就能與機器無關(machine-independent)。size_type 就是這些配套類型中的一種。它定義為與 unsigned 型(unsignedint 或 unsignedlong)具有相同的含義,而且可以保證足夠大能夠存儲任意 string 對象的長度。為了使用由 string 類型定義的 size_type 類型是由 string 類定義。
![]() |
Anyvariable used to store the result from thestringsize operation ought to be of typestring::size_type.It is particularly important not to assign the return fromsizeto an int. 任何存儲 string 的 size 操作結果的變量必須為 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 correspondingsigned type 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 anint isthat 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 largest string an intcould represent would have 32,767 characters. Astringthat held the contents of a file could easily exceed this size. Thesafest way to hold thesize ofa string is to use the typethe library defines for this purpose, which isstring::size_type.
使用 int 變量的另一個問題是,有些機器上 int 變量的表示范圍太小,甚至無法存儲實際並不長的 string 對象。如在有 16 位 int 型的機器上,int 類型變量最大只能表示 32767 個字符的 string 個字符的 string 對象。而能容納一個文件內容的 string 對象輕易就會超過這個數字。因此,為了避免溢出,保存一個 stirng 對象 size 的最安全的方法就是使用標准庫類型 string::size_type。
Thestring Relational Operators
string 關系操作符
Thestring class defines severaloperators that compare twostringvalues. Each of these operators works by comparing the charactersfrom eachstring.
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,returning true if they areequal. Two strings are equalif they are the same length and contain the same characters. Thelibrary also defines!= totest whether two strings areunequal.
== 操作符比較兩個 string 對象,如果它們相等,則返回 true。兩個 string 對象相等是指它們的長度相同,且含有相同的字符。標准庫還定義了 != 操作符來測試兩個 string 對象是否不等。
Therelational operators<, <=, >, >=test whether onestring isless 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 shorterstring isless 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 the strings
舉例來說,給定 string 對象;
string substr = "Hello"; string phrase = "Hello World"; string slang = "Hiya";
thensubstris less than phrase, and slangis greater than eithersubstror phrase.
則 substr 小於 phrase,而 slang 則大於 substr 或 phrase
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 of strings,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,st1 contains acopy of the characters inst2.
賦值操作后,st1 就包含了 st2 串所有字符的一個副本。
Moststring library 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 thirdstring asfollows:
下面把兩個 string 對象連接起來產生第三個 string 對象:
string s3 = s1 + s2; // s3 is hello, world\n
If wewanted to appends2 to s1directly, then we would use+=:
如果要把 s2 直接追加到 s1 的末尾,可以使用 += 操作符:
s1 += s2; // equivalent to s1 = s1 + s2
AddingCharacter String Literals andstrings
和字符串字面值的連接
Thestringss1and s2 included punctuationdirectly. We could achieve the same result by mixingstringobjects and string literals as follows:
上面的字符串對象 s1 和 s2 直接包含了標點符號。也可以通過將 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 of stringtype:
當進行 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 ofs3 and s4involve only a single operation. In these cases, it is easy todetermine that the initialization ofs3is legal: We initializes3 byadding a string and a stringliteral. The initialization ofs4attempts to add two string literals and is illegal.
s3 和 s4 的初始化只用了一個單獨的操作。在這些例子中,很容易判斷 s3 的初始化是合法的:把一個 string 對象和一個字符串字面值連接起來。而 s4 的初始化試圖將兩個字符串字面值相加,因此是非法的。
Theinitialization ofs5 mayappear 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 subexpression s1 + ", "returns a string, 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 對象獲取字符
Thestring type uses the subscript([ ]) operator to access theindividual characters in the string.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)
![]() |
Subscriptsforstrings start at zero;ifs is a string,then ifs isn'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, assumingsomevaland someotherval are integralobjects, we could write
任何可產生整型值的表達式可用作下標操作符的索引。例如,假設 someval 和 someotherval 是兩個整形對象,可以這樣寫:
str[someotherval * someval] = someval;
Althoughany integral type can be used as an index, the actual type of theindex isstring::size_type,which is anunsigned type.
雖然任何整型數值都可作為索引,但索引的實際數據類型卻是類型 unsigned 類型 string::size_type。
![]() |
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 the stringminus one. By using astring::size_typeor anotherunsigned type 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 類型的值,其取值范圍在 0 到 string 對象長度減 1 之間。使用 string::size_type 類型或其他 unsigned 類型,就只需要檢測它是否小於 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.3 on the facing page lists thefunctions that can be used on the characters in a string(or on any otherchar value).These functions are defined in thecctypeheader.
我們經常要對 string 對象中的單個字符進行處理,例如,通常需要知道某個特殊字符是否為空白字符、字母或數字。表3.3 列出了各種字符操作函數,適用於 string 對象的字符(或其他任何 char 值)。這些函數都在 cctype 頭文件中定義。
Table3.3.cctype Functions
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, thetolowerand toupper functions return acharactereither the argument unchanged or the lower- or uppercaseversion of the character. We could usetolowerto change s to lowercase asfollows:
和返回真值的函數不同的是,tolower 和 toupper 函數返回的是字符,返回實參字符本身或返回該字符相應的大小寫字符。我們可以用 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!!!
ExercisesSection 3.2.4
|