string流


一、C++中字符串(String)

字符串(String):就是(可能是空的)字符序列。
C++中的字符串在概念上和Java中的字符串类似。

C++字符串用string类型来表示。在使用string类型之前,必须在程序中包含如下头文件
  1. #include <string>  
#include <string>

可以通过调用如下方法:
  1. str.length()  
str.length()
来获取字符串中字符的长度。

可以通过如下方式来从一个字符串中读取一个字符
  1. str[index]  
str[index]
尽管字符串不是数组,但是上述语法是一个方便的语法方式。

字符操作
在C++中,头文件<cctype>包含各种有用的处理字符的函数,以下函数用来检查给定的类型是否是一个给定的字符
isalpha, isdigit, isalnum, islower, isupper, isspace, ispunct.

跟Java中字符串不同,C++中字符串是可变的,可以被修改。
改变单个字符的方式:
  1. str[index] = ch  
str[index] = ch

附加更多的文本方式:
  1. str += text  
str += text

这些操作直接改变字符串本身,而不是对字符串的副本进行操作。

在C++中,==操作符可以直接拿来用于字符串的比较
  1. if(str1 == str2)  
  2. {  
  3.     /* string match */  
  4. }  
if(str1 == str2)
{
    /* string match */
}

在一个字符串中查询其他一些字符,可以使用find,如果找不到,则返回string::npos,而不是-1。
  1. if(str1.find(str2) != string::npos)  
  2. {  
  3.     /* found str2 inside str1 */  
  4. }  
if(str1.find(str2) != string::npos)
{
    /* found str2 inside str1 */
}

通过调用substr方法从string中获取substring。
substr方法需要知道substring的开始位置和长度(不是结束位置)
  1. string allButFirstChar = str.substr(1);  
  2. string lastFiveChars = str.substr(str.length() - 5, 5);  
string allButFirstChar = str.substr(1);
string lastFiveChars = str.substr(str.length() - 5, 5);


与Java语言不同的时,在C++中,只能连接字符串和字符到其他的字符串中。

在本课程中,提供了"strlib.h"库一、C++中字符串(String)


字符串(String):就是(可能是空的)字符序列。

C++中的字符串在概念上和Java中的字符串类似。




C++字符串用string类型来表示。在使用string类型之前,必须在程序中包含如下头文件




[cpp] view plaincopy
01.#include <string>


可以通过调用如下方法:



[cpp] view plaincopy
01.str.length()

来获取字符串中字符的长度。



可以通过如下方式来从一个字符串中读取一个字符




[cpp] view plaincopy
01.str[index]

尽管字符串不是数组,但是上述语法是一个方便的语法方式。



字符操作

在C++中,头文件<cctype>包含各种有用的处理字符的函数,以下函数用来检查给定的类型是否是一个给定的字符

isalpha, isdigit, isalnum, islower, isupper, isspace, ispunct.




跟Java中字符串不同,C++中字符串是可变的,可以被修改。

改变单个字符的方式:




[cpp] view plaincopy
01.str[index] = ch





附加更多的文本方式:




[cpp] view plaincopy
01.str += text


这些操作直接改变字符串本身,而不是对字符串的副本进行操作。



在C++中,==操作符可以直接拿来用于字符串的比较




[cpp] view plaincopy
01.if(str1 == str2)
02.{
03. /* string match */
04.}


在一个字符串中查询其他一些字符,可以使用find,如果找不到,则返回string::npos,而不是-1。



[cpp] view plaincopy
01.if(str1.find(str2) != string::npos)
02.{
03. /* found str2 inside str1 */
04.}


通过调用substr方法从string中获取substring。
substr方法需要知道substring的开始位置和长度(不是结束位置)




[cpp] view plaincopy
01.string allButFirstChar = str.substr(1);
02.string lastFiveChars = str.substr(str.length() - 5, 5);




与Java语言不同的时,在C++中,只能连接字符串和字符到其他的字符串中。




在本课程中,提供了"strlib.h"库,让字符串操作更加容易




[cpp] view plaincopy
01.string s = "I like " + integerToString(137);

strlib.h的代码如下:



[cpp] view plaincopy
01./*
02. * File: strlib.h
03. * --------------
04. * This file exports several useful string functions that are not
05. * included in the C++ string library.
06. */
07.
08.#ifndef _strlib_h
09.#define _strlib_h
10.
11.#include <iostream>
12.#include <string>
13.
14./*
15. * Function: integerToString
16. * Usage: string s = integerToString(n);
17. * -------------------------------------
18. * Converts an integer into the corresponding string of digits.
19. * For example, calling <code>integerToString(123)</code> returns
20. * the string <code>"123"</code>.
21. */
22.
23.std::string integerToString(int n);
24.
25./*
26. * Function: stringToInteger
27. * Usage: int n = stringToInteger(str);
28. * ------------------------------------
29. * Converts a string of digits into an integer. If the string is not a
30. * legal integer or contains extraneous characters other than whitespace,
31. * <code>stringToInteger</code> calls <code>error</code> with an
32. * appropriate message.
33. */
34.
35.int stringToInteger(std::string str);
36.
37./*
38. * Function: realToString
39. * Usage: string s = realToString(d);
40. * ----------------------------------
41. * Converts a floating-point number into the corresponding string form.
42. * For example, calling <code>realToString(23.45)</code> returns
43. * the string <code>"23.45"</code>.
44. */
45.
46.std::string realToString(double d);
47.
48./*
49. * Function: stringToReal
50. * Usage: double d = stringToReal(str);
51. * ------------------------------------
52. * Converts a string representing a real number into its corresponding
53. * value. If the string is not a legal floating-point number or contains
54. * extraneous characters other than whitespace, <code>stringToReal</code>
55. * calls <code>error</code> with an appropriate message.
56. */
57.
58.double stringToReal(std::string str);
59.
60./*
61. * Function: toUpperCase
62. * Usage: string s = toUpperCase(str);
63. * -----------------------------------
64. * Returns a new string in which all lowercase characters have been converted
65. * into their uppercase equivalents.
66. */
67.
68.std::string toUpperCase(std::string str);
69.
70./*
71. * Function: toLowerCase
72. * Usage: string s = toLowerCase(str);
73. * -----------------------------------
74. * Returns a new string in which all uppercase characters have been converted
75. * into their lowercase equivalents.
76. */
77.
78.std::string toLowerCase(std::string str);
79.
80./*
81. * Function: equalsIgnoreCase
82. * Usage: if (equalsIgnoreCase(s1, s2)) ...
83. * ----------------------------------------
84. * Returns <code>true</code> if <code>s1</code> and <code>s2</code> are
85. * equal discounting differences in case.
86. */
87.
88.bool equalsIgnoreCase(std::string s1, std::string s2);
89.
90./*
91. * Function: startsWith
92. * Usage: if (startsWith(str, prefix)) ...
93. * ---------------------------------------
94. * Returns <code>true</code> if the string <code>str</code> starts with
95. * the specified prefix, which may be either a string or a character.
96. */
97.
98.bool startsWith(std::string str, std::string prefix);
99.bool startsWith(std::string str, char prefix);
100.
101./*
102. * Function: endsWith
103. * Usage: if (endsWith(str, suffix)) ...
104. * -------------------------------------
105. * Returns <code>true</code> if the string <code>str</code> ends with
106. * the specified suffix, which may be either a string or a character.
107. */
108.
109.bool endsWith(std::string str, std::string suffix);
110.bool endsWith(std::string str, char suffix);
111.
112./*
113. * Function: trim
114. * Usage: string trimmed = trim(str);
115. * ----------------------------------
116. * Returns a new string after removing any whitespace characters
117. * from the beginning and end of the argument.
118. */
119.
120.std::string trim(std::string str);
121.
122./* Private section */
123.
124./**********************************************************************/
125./* Note: Everything below this point in the file is logically part */
126./* of the implementation and should not be of interest to clients. */
127./**********************************************************************/
128.
129./*
130. * Friend function: writeQuotedString
131. * Usage: writeQuotedString(outfile, str, forceQuotes);
132. * ----------------------------------------------------
133. * Writes the string str to outfile surrounded by double quotes, converting
134. * special characters to escape sequences, as necessary. If the optional
135. * parameter forceQuotes is explicitly set to false, quotes are included
136. * in the output only if necessary.
137. */
138.
139.void writeQuotedString(std::ostream & os, const std::string & str,
140. bool forceQuotes = true);
141.
142./*
143. * Friend function: readQuotedString
144. * Usage: readQuotedString(infile, str);
145. * -------------------------------------
146. * Reads the next string from infile into the reference parameter str.
147. * If the first character (other than whitespace) is either a single
148. * or a double quote, this function reads characters up to the
149. * matching quote, processing standard escape sequences as it goes.
150. * If not, readString reads characters up to any of the characters
151. * in the string STRING_DELIMITERS in the implementation file.
152. */
153.
154.void readQuotedString(std::istream & is, std::string & str);
155.
156./*
157. * Friend function: stringNeedsQuoting
158. * Usage: if (stringNeedsQuoting(str)) ...
159. * ---------------------------------------
160. * Checks whether the string needs quoting in order to be read correctly.
161. */
162.
163.bool stringNeedsQuoting(const std::string & str);
164.
165./*
166. * Friend function: writeGenericValue
167. * Usage: writeGenericValue(os, value, forceQuotes);
168. * -------------------------------------------------
169. * Writes a generic value to the output stream. If that value is a string,
170. * this function uses writeQuotedString to write the value.
171. */
172.
173.template <typename ValueType>
174.void writeGenericValue(std::ostream & os, const ValueType & value,
175. bool forceQuotes) {
176. os << value;
177.}
178.
179.template <>
180.inline void writeGenericValue(std::ostream & os, const std::string & value,
181. bool forceQuotes) {
182. writeQuotedString(os, value, forceQuotes);
183.}
184.
185./*
186. * Friend function: readGenericValue
187. * Usage: readGenericValue(is, value);
188. * -----------------------------------
189. * Reads a generic value from the input stream. If that value is a string,
190. * this function uses readQuotedString to read the value.
191. */
192.
193.template <typename ValueType>
194.void readGenericValue(std::istream & is, ValueType & value) {
195. is >> value;
196.}
197.
198.template <>
199.inline void readGenericValue(std::istream & is, std::string & value) {
200. readQuotedString(is, value);
201.}
202.
203.
204.#endif


strlib.c的代码如下:



[cpp] view plaincopy
01./*
02. * File: strlib.cpp
03. * ----------------
04. * This file implements the strlib.h interface.
05. */
06.
07.#include <cctype>
08.#include <iostream>
09.#include <sstream>
10.#include "error.h"
11.#include "strlib.h"
12.using namespace std;
13.
14./* Function prototypes */
15.
16./*
17. * Implementation notes: numeric conversion
18. * ----------------------------------------
19. * These functions use the <sstream> library to perform the conversion.
20. */
21.
22.string integerToString(int n) {
23. ostringstream stream;
24. stream << n;
25. return stream.str();
26.}
27.
28.int stringToInteger(string str) {
29. istringstream stream(str);
30. int value;
31. stream >> value >> ws;
32. if (stream.fail() || !stream.eof()) {
33. error("stringToInteger: Illegal integer format (" + str + ")");
34. }
35. return value;
36.}
37.
38.string realToString(double d) {
39. ostringstream stream;
40. stream << uppercase << d;
41. return stream.str();
42.}
43.
44.double stringToReal(string str) {
45. istringstream stream(str);
46. double value;
47. stream >> value >> ws;
48. if (stream.fail() || !stream.eof()) {
49. error("stringToReal: Illegal floating-point format (" + str + ")");
50. }
51. return value;
52.}
53.
54./*
55. * Implementation notes: case conversion
56. * -------------------------------------
57. * The functions toUpperCase and toLowerCase return a new string whose
58. * characters appear in the desired case. These implementations rely on
59. * the fact that the characters in the string are copied when the
60. * argument is passed to the function, which makes it possible to change
61. * the case of the copy without affecting the original.
62. */
63.
64.string toUpperCase(string str) {
65. int nChars = str.length();
66. for (int i = 0; i < nChars; i++) {
67. str[i] = toupper(str[i]);
68. }
69. return str;
70.}
71.
72.string toLowerCase(string str) {
73. int nChars = str.length();
74. for (int i = 0; i < nChars; i++) {
75. str[i] = tolower(str[i]);
76. }
77. return str;
78.}
79.
80./*
81. * Implementation notes: equalsIgnoreCase
82. * --------------------------------------
83. * This implementation uses a for loop to cycle through the characters in
84. * each string. Converting each string to uppercase and then comparing
85. * the results makes for a shorter but less efficient implementation.
86. */
87.
88.bool equalsIgnoreCase(string s1, string s2) {
89. if (s1.length() != s2.length()) return false;
90. int nChars = s1.length();
91. for (int i = 0; i < nChars; i++) {
92. if (tolower(s1[i]) != tolower(s2[i])) return false;
93. }
94. return true;
95.}
96.
97./*
98. * Implementation notes: startsWith, endsWith
99. * ------------------------------------------
100. * These implementations are overloaded to allow the second argument to
101. * be either a string or a character.
102. */
103.
104.bool startsWith(string str, string prefix) {
105. if (str.length() < prefix.length()) return false;
106. int nChars = prefix.length();
107. for (int i = 0; i < nChars; i++) {
108. if (str[i] != prefix[i]) return false;
109. }
110. return true;
111.}
112.
113.bool startsWith(string str, char prefix) {
114. return str.length() > 0 && str[0] == prefix;
115.}
116.
117.bool endsWith(string str, string suffix) {
118. int nChars = suffix.length();
119. int start = str.length() - nChars;
120. if (start < 0) return false;
121. for (int i = 0; i < nChars; i++) {
122. if (str[start + i] != suffix[i]) return false;
123. }
124. return true;
125.}
126.
127.bool endsWith(string str, char suffix) {
128. return str.length() > 0 && str[str.length() - 1] == suffix;
129.}
130.
131.string trim(string str) {
132. int finish = str.length() - 1;
133. while (finish >= 0 && isspace(str[finish])) {
134. finish--;
135. }
136. int start = 0;
137. while (start <= finish && isspace(str[start])) {
138. start++;
139. }
140. return str.substr(start, finish - start + 1);
141.}
142.
143./*
144. * Implementation notes: readQuotedString and writeQuotedString
145. * ------------------------------------------------------------
146. * Most of the work in these functions has to do with escape sequences.
147. */
148.
149.static const string STRING_DELIMITERS = ",:)}]\n";
150.
151.bool stringNeedsQuoting(const string & str) {
152. int n = str.length();
153. for (int i = 0; i < n; i++) {
154. char ch = str[i];
155. if (isspace(ch)) return false;
156. if (STRING_DELIMITERS.find(ch) != string::npos) return true;
157. }
158. return false;
159.}
160.
161.void readQuotedString(istream & is, string & str) {
162. str = "";
163. char ch;
164. while (is.get(ch) && isspace(ch)) {
165. /* Empty */
166. }
167. if (is.fail()) return;
168. if (ch == '\'' || ch == '"') {
169. char delim = ch;
170. while (is.get(ch) && ch != delim) {
171. if (is.fail()) error("Unterminated string");
172. if (ch == '\\') {
173. if (!is.get(ch)) error("Unterminated string");
174. if (isdigit(ch) || ch == 'x') {
175. int base = 8;
176. if (ch == 'x') base = 16;
177. int result = 0;
178. int digit = 0;
179. while (ch != delim) {
180. if (isdigit(ch)) {
181. digit = ch - '0';
182. } else if (isalpha(ch)) {
183. digit = toupper(ch) - 'A' + 10;
184. } else {
185. digit = base;
186. }
187. if (digit >= base) break;
188. result = base * result + digit;
189. if (!is.get(ch)) error("Unterminated string");
190. }
191. ch = char(result);
192. is.unget();
193. } else {
194. switch (ch) {
195. case 'a': ch = '\a'; break;
196. case 'b': ch = '\b'; break;
197. case 'f': ch = '\f'; break;
198. case 'n': ch = '\n'; break;
199. case 'r': ch = '\r'; break;
200. case 't': ch = '\t'; break;
201. case 'v': ch = '\v'; break;
202. case '"': ch = '"'; break;
203. case '\'': ch = '\''; break;
204. case '\\': ch = '\\'; break;
205. }
206. }
207. }
208. str += ch;
209. }
210. } else {
211. str += ch;
212. int endTrim = 0;
213. while (is.get(ch) && STRING_DELIMITERS.find(ch) == string::npos) {
214. str += ch;
215. if (!isspace(ch)) endTrim = str.length();
216. }
217. if (is) is.unget();
218. str = str.substr(0, endTrim);
219. }
220.}
221.
222.void writeQuotedString(ostream & os, const string & str, bool forceQuotes) {
223. if (!forceQuotes && stringNeedsQuoting(str)) forceQuotes = true;
224. if (forceQuotes) os << '"';
225. int len = str.length();
226. for (int i = 0; i < len; i++) {
227. char ch = str.at(i);
228. switch (ch) {
229. case '\a': os << "\\a"; break;
230. case '\b': os << "\\b"; break;
231. case '\f': os << "\\f"; break;
232. case '\n': os << "\\n"; break;
233. case '\r': os << "\\r"; break;
234. case '\t': os << "\\t"; break;
235. case '\v': os << "\\v"; break;
236. case '"': os << oct << "\\" << (int(ch) & 0xFF); break;
237. case '\\': os << "\\\\"; break;
238. default:
239. if (isprint(ch)) {
240. os << ch;
241. } else {
242. ostringstream oss;
243. oss << oct << (int(ch) & 0xFF);
244. os << "\\" << oss.str();
245. }
246. }
247. }
248. if (forceQuotes) os << '"';
249.}


在C++中,有两种类型的字符串:
•C类型字符串,来自于C编程语言
•C++类型string,C++实现的库

在C++中,尽可能的使用string类型。




对于string s = "Nubian " + "ibex";

这些字符串是C风格的,C风格的字符串是不支持+操作的,该表达式编译不通过。改为如下:

string s = string("Nubian ") + "ibex";

现在显式的转换C风格的字符串为C++类型的字符串,这样该代码是合法的。



二、字符串中的递归操作

1.对一个字符串进行逆序操作
递归的对字符串进行逆序操作,如下示意图所示:




代码实现如下:




[cpp] view plaincopy
01./* File: reverse.cpp
02. *
03. * Code to recursively reverse a string.
04. */
05.#include <iostream>
06.#include <string>
07.#include "simpio.h"
08.using namespace std;
09.
10.string reverseString(string line);
11.
12.int main() {
13. string line = getLine("Enter a string: ");
14. cout << reverseString(line) << endl;
15.}
16.
17./* Returns the reverse of the indicated string. */
18.string reverseString(string line) {
19. /* If the string is empty, it's its own reverse */
20. if (line == "") {
21. return "";
22. }
23. /* Otherwise, reverse all but the first character, then tack
24. * on the first character.
25. */
26. else {
27. return reverseString(line.substr(1)) + line[0];
28. }
29.}


2.回文(palindrome)
回文就是给定的字符串是对称的。

递归的判断给定的字符串是否是回文,示意图如下:




代码实现如下:




[cpp] view plaincopy
01./* File: palindrome.cpp
02. *
03. * A program that reads a file of English words, then prints out all
04. * the palindromic words.
05. */
06.#include <iostream>
07.#include <string>
08.#include <fstream>
09.#include "simpio.h"
10.using namespace std;
11.
12.bool isPalindrome(string text);
13.
14.int main() {
15. /* Open the file for reading. We really should check whether
16. * the file is open before proceeding.
17. */
18. string file = "dictionary.txt";
19. ifstream input(file.c_str());
20.
21. /* Read each line of the file and print out those that are palindromes. */
22. string line;
23. while (getline(input, line)) {
24. if (isPalindrome(line)) {
25. cout << line << endl;
26. }
27. }
28.
29. return 0;
30.}
31.
32./* Returns whether the given string is a palindrome. */
33.bool isPalindrome(string text) {
34. /* All characters of length 0 or length 1 are guaranteed to
35. * be palindromes.
36. */
37. if (text.length() <= 1) {
38. return true;
39. }
40. /* If the first and last character of the string aren't the same,
41. * the string cannot be a palindrome.
42. */
43. else if (text[0] != text[text.length() - 1]) {
44. return false;
45. }
46. /* Otherwise, this string is a palindrome precisely when the middle
47. * characters are a palindrome.
48. */
49. else {
50. return isPalindrome(text.substr(1, text.length() - 2));
51. }
52.}


3.C++中从File中读取数据

既然我们知道了如何操作字符串了,那么我们开始从外部文件中读取数据来处理。

在C++中,文件读取使用ifstream类来进行处理。必须包含头文件#include <fstream>来使用ifstream。




1)逐行读取

ifstream类通过使用getline函数从文件中读取一行




[cpp] view plaincopy
01.getline(file, str);


典型的读取文件中各行的循环如下所示:



[cpp] view plaincopy
01.string line;
02.while(getline(file, line))
03.{
04. /* ...process line... */
05.}


回文的实现代码使用了文件的读取。



读取格式化的数据

从文件中读取格式化的数据可以通过使用流提取操作符:file>>variable

可以读取任何原始类型和字符串

当读取字符串时,在换行符或空格处即停止。




典型的读取格式化数据循环如下:




[cpp] view plaincopy
01.type val;
02.while(file >> val)
03.{
04. /* ... process val... */
05.}


4.C++中参数传递

在C++中,有两种方法传递一个参数给一个函数:

•传值方式:参数通过拷贝传给一个函数。void myFunction(int x);
•引用方式:传递给函数的变量在函数中是可以改变的。void myFunction(int &x)

举例:




[cpp] view plaincopy
01.int main()
02.{
03. int x = 10;
04. int y = 20;
05.
06. //here: x = 10, y = 20
07. sum(x, y);
08. //here: x = 10, y = 20
09. swap(x, y);
10. //here: x = 20, y = 10
11. cout << x << " " << y << endl;
12.
13. return 0;
14.}
15.
16.//Pass by reference
17.void swap(int &x, int &y)
18.{
19. int temp = x;
20. x = y;
21. y = temp;
22.}
23.
24.//Pass by value
25.void printSum(int x, int y)
26.{
27. x += y;
28. cout << x << endl;
29.}
,让字符串操作更加容易
  1. string s = "I like " + integerToString(137);  
string s = "I like " + integerToString(137);
strlib.h的代码如下:
  1. /* 
  2.  * File: strlib.h 
  3.  * -------------- 
  4.  * This file exports several useful string functions that are not 
  5.  * included in the C++ string library. 
  6.  */  
  7.   
  8. #ifndef _strlib_h  
  9. #define _strlib_h  
  10.   
  11. #include <iostream>  
  12. #include <string>  
  13.   
  14. /* 
  15.  * Function: integerToString 
  16.  * Usage: string s = integerToString(n); 
  17.  * ------------------------------------- 
  18.  * Converts an integer into the corresponding string of digits. 
  19.  * For example, calling <code>integerToString(123)</code> returns 
  20.  * the string <code>"123"</code>. 
  21.  */  
  22.   
  23. std::string integerToString(int n);  
  24.   
  25. /* 
  26.  * Function: stringToInteger 
  27.  * Usage: int n = stringToInteger(str); 
  28.  * ------------------------------------ 
  29.  * Converts a string of digits into an integer.  If the string is not a 
  30.  * legal integer or contains extraneous characters other than whitespace, 
  31.  * <code>stringToInteger</code> calls <code>error</code> with an 
  32.  * appropriate message. 
  33.  */  
  34.   
  35. int stringToInteger(std::string str);  
  36.   
  37. /* 
  38.  * Function: realToString 
  39.  * Usage: string s = realToString(d); 
  40.  * ---------------------------------- 
  41.  * Converts a floating-point number into the corresponding string form. 
  42.  * For example, calling <code>realToString(23.45)</code> returns 
  43.  * the string <code>"23.45"</code>. 
  44.  */  
  45.   
  46. std::string realToString(double d);  
  47.   
  48. /* 
  49.  * Function: stringToReal 
  50.  * Usage: double d = stringToReal(str); 
  51.  * ------------------------------------ 
  52.  * Converts a string representing a real number into its corresponding 
  53.  * value.  If the string is not a legal floating-point number or contains 
  54.  * extraneous characters other than whitespace, <code>stringToReal</code> 
  55.  * calls <code>error</code> with an appropriate message. 
  56.  */  
  57.   
  58. double stringToReal(std::string str);  
  59.   
  60. /* 
  61.  * Function: toUpperCase 
  62.  * Usage: string s = toUpperCase(str); 
  63.  * ----------------------------------- 
  64.  * Returns a new string in which all lowercase characters have been converted 
  65.  * into their uppercase equivalents. 
  66.  */  
  67.   
  68. std::string toUpperCase(std::string str);  
  69.   
  70. /* 
  71.  * Function: toLowerCase 
  72.  * Usage: string s = toLowerCase(str); 
  73.  * ----------------------------------- 
  74.  * Returns a new string in which all uppercase characters have been converted 
  75.  * into their lowercase equivalents. 
  76.  */  
  77.   
  78. std::string toLowerCase(std::string str);  
  79.   
  80. /* 
  81.  * Function: equalsIgnoreCase 
  82.  * Usage: if (equalsIgnoreCase(s1, s2)) ... 
  83.  * ---------------------------------------- 
  84.  * Returns <code>true</code> if <code>s1</code> and <code>s2</code> are 
  85.  * equal discounting differences in case. 
  86.  */  
  87.   
  88. bool equalsIgnoreCase(std::string s1, std::string s2);  
  89.   
  90. /* 
  91.  * Function: startsWith 
  92.  * Usage: if (startsWith(str, prefix)) ... 
  93.  * --------------------------------------- 
  94.  * Returns <code>true</code> if the string <code>str</code> starts with 
  95.  * the specified prefix, which may be either a string or a character. 
  96.  */  
  97.   
  98. bool startsWith(std::string str, std::string prefix);  
  99. bool startsWith(std::string str, char prefix);  
  100.   
  101. /* 
  102.  * Function: endsWith 
  103.  * Usage: if (endsWith(str, suffix)) ... 
  104.  * ------------------------------------- 
  105.  * Returns <code>true</code> if the string <code>str</code> ends with 
  106.  * the specified suffix, which may be either a string or a character. 
  107.  */  
  108.   
  109. bool endsWith(std::string str, std::string suffix);  
  110. bool endsWith(std::string str, char suffix);  
  111.   
  112. /* 
  113.  * Function: trim 
  114.  * Usage: string trimmed = trim(str); 
  115.  * ---------------------------------- 
  116.  * Returns a new string after removing any whitespace characters 
  117.  * from the beginning and end of the argument. 
  118.  */  
  119.   
  120. std::string trim(std::string str);  
  121.   
  122. /* Private section */  
  123.   
  124. /**********************************************************************/  
  125. /* Note: Everything below this point in the file is logically part    */  
  126. /* of the implementation and should not be of interest to clients.    */  
  127. /**********************************************************************/  
  128.   
  129. /* 
  130.  * Friend function: writeQuotedString 
  131.  * Usage: writeQuotedString(outfile, str, forceQuotes); 
  132.  * ---------------------------------------------------- 
  133.  * Writes the string str to outfile surrounded by double quotes, converting 
  134.  * special characters to escape sequences, as necessary.  If the optional 
  135.  * parameter forceQuotes is explicitly set to false, quotes are included 
  136.  * in the output only if necessary. 
  137.  */  
  138.   
  139. void writeQuotedString(std::ostream & os, const std::string & str,  
  140.                        bool forceQuotes = true);  
  141.   
  142. /* 
  143.  * Friend function: readQuotedString 
  144.  * Usage: readQuotedString(infile, str); 
  145.  * ------------------------------------- 
  146.  * Reads the next string from infile into the reference parameter str. 
  147.  * If the first character (other than whitespace) is either a single 
  148.  * or a double quote, this function reads characters up to the 
  149.  * matching quote, processing standard escape sequences as it goes. 
  150.  * If not, readString reads characters up to any of the characters 
  151.  * in the string STRING_DELIMITERS in the implementation file. 
  152.  */  
  153.   
  154. void readQuotedString(std::istream & is, std::string & str);  
  155.   
  156. /* 
  157.  * Friend function: stringNeedsQuoting 
  158.  * Usage: if (stringNeedsQuoting(str)) ... 
  159.  * --------------------------------------- 
  160.  * Checks whether the string needs quoting in order to be read correctly. 
  161.  */  
  162.   
  163. bool stringNeedsQuoting(const std::string & str);  
  164.   
  165. /* 
  166.  * Friend function: writeGenericValue 
  167.  * Usage: writeGenericValue(os, value, forceQuotes); 
  168.  * ------------------------------------------------- 
  169.  * Writes a generic value to the output stream.  If that value is a string, 
  170.  * this function uses writeQuotedString to write the value. 
  171.  */  
  172.   
  173. template <typename ValueType>  
  174. void writeGenericValue(std::ostream & os, const ValueType & value,  
  175.                        bool forceQuotes) {  
  176.    os << value;  
  177. }  
  178.   
  179. template <>  
  180. inline void writeGenericValue(std::ostream & os, const std::string & value,  
  181.                               bool forceQuotes) {  
  182.    writeQuotedString(os, value, forceQuotes);  
  183. }  
  184.   
  185. /* 
  186.  * Friend function: readGenericValue 
  187.  * Usage: readGenericValue(is, value); 
  188.  * ----------------------------------- 
  189.  * Reads a generic value from the input stream.  If that value is a string, 
  190.  * this function uses readQuotedString to read the value. 
  191.  */  
  192.   
  193. template <typename ValueType>  
  194. void readGenericValue(std::istream & is, ValueType & value) {  
  195.    is >> value;  
  196. }  
  197.   
  198. template <>  
  199. inline void readGenericValue(std::istream & is, std::string & value) {  
  200.    readQuotedString(is, value);  
  201. }  
  202.   
  203.   
  204. #endif  
/*
 * File: strlib.h
 * --------------
 * This file exports several useful string functions that are not
 * included in the C++ string library.
 */

#ifndef _strlib_h
#define _strlib_h

#include <iostream>
#include <string>

/*
 * Function: integerToString
 * Usage: string s = integerToString(n);
 * -------------------------------------
 * Converts an integer into the corresponding string of digits.
 * For example, calling <code>integerToString(123)</code> returns
 * the string <code>"123"</code>.
 */

std::string integerToString(int n);

/*
 * Function: stringToInteger
 * Usage: int n = stringToInteger(str);
 * ------------------------------------
 * Converts a string of digits into an integer.  If the string is not a
 * legal integer or contains extraneous characters other than whitespace,
 * <code>stringToInteger</code> calls <code>error</code> with an
 * appropriate message.
 */

int stringToInteger(std::string str);

/*
 * Function: realToString
 * Usage: string s = realToString(d);
 * ----------------------------------
 * Converts a floating-point number into the corresponding string form.
 * For example, calling <code>realToString(23.45)</code> returns
 * the string <code>"23.45"</code>.
 */

std::string realToString(double d);

/*
 * Function: stringToReal
 * Usage: double d = stringToReal(str);
 * ------------------------------------
 * Converts a string representing a real number into its corresponding
 * value.  If the string is not a legal floating-point number or contains
 * extraneous characters other than whitespace, <code>stringToReal</code>
 * calls <code>error</code> with an appropriate message.
 */

double stringToReal(std::string str);

/*
 * Function: toUpperCase
 * Usage: string s = toUpperCase(str);
 * -----------------------------------
 * Returns a new string in which all lowercase characters have been converted
 * into their uppercase equivalents.
 */

std::string toUpperCase(std::string str);

/*
 * Function: toLowerCase
 * Usage: string s = toLowerCase(str);
 * -----------------------------------
 * Returns a new string in which all uppercase characters have been converted
 * into their lowercase equivalents.
 */

std::string toLowerCase(std::string str);

/*
 * Function: equalsIgnoreCase
 * Usage: if (equalsIgnoreCase(s1, s2)) ...
 * ----------------------------------------
 * Returns <code>true</code> if <code>s1</code> and <code>s2</code> are
 * equal discounting differences in case.
 */

bool equalsIgnoreCase(std::string s1, std::string s2);

/*
 * Function: startsWith
 * Usage: if (startsWith(str, prefix)) ...
 * ---------------------------------------
 * Returns <code>true</code> if the string <code>str</code> starts with
 * the specified prefix, which may be either a string or a character.
 */

bool startsWith(std::string str, std::string prefix);
bool startsWith(std::string str, char prefix);

/*
 * Function: endsWith
 * Usage: if (endsWith(str, suffix)) ...
 * -------------------------------------
 * Returns <code>true</code> if the string <code>str</code> ends with
 * the specified suffix, which may be either a string or a character.
 */

bool endsWith(std::string str, std::string suffix);
bool endsWith(std::string str, char suffix);

/*
 * Function: trim
 * Usage: string trimmed = trim(str);
 * ----------------------------------
 * Returns a new string after removing any whitespace characters
 * from the beginning and end of the argument.
 */

std::string trim(std::string str);

/* Private section */

/**********************************************************************/
/* Note: Everything below this point in the file is logically part    */
/* of the implementation and should not be of interest to clients.    */
/**********************************************************************/

/*
 * Friend function: writeQuotedString
 * Usage: writeQuotedString(outfile, str, forceQuotes);
 * ----------------------------------------------------
 * Writes the string str to outfile surrounded by double quotes, converting
 * special characters to escape sequences, as necessary.  If the optional
 * parameter forceQuotes is explicitly set to false, quotes are included
 * in the output only if necessary.
 */

void writeQuotedString(std::ostream & os, const std::string & str,
                       bool forceQuotes = true);

/*
 * Friend function: readQuotedString
 * Usage: readQuotedString(infile, str);
 * -------------------------------------
 * Reads the next string from infile into the reference parameter str.
 * If the first character (other than whitespace) is either a single
 * or a double quote, this function reads characters up to the
 * matching quote, processing standard escape sequences as it goes.
 * If not, readString reads characters up to any of the characters
 * in the string STRING_DELIMITERS in the implementation file.
 */

void readQuotedString(std::istream & is, std::string & str);

/*
 * Friend function: stringNeedsQuoting
 * Usage: if (stringNeedsQuoting(str)) ...
 * ---------------------------------------
 * Checks whether the string needs quoting in order to be read correctly.
 */

bool stringNeedsQuoting(const std::string & str);

/*
 * Friend function: writeGenericValue
 * Usage: writeGenericValue(os, value, forceQuotes);
 * -------------------------------------------------
 * Writes a generic value to the output stream.  If that value is a string,
 * this function uses writeQuotedString to write the value.
 */

template <typename ValueType>
void writeGenericValue(std::ostream & os, const ValueType & value,
                       bool forceQuotes) {
   os << value;
}

template <>
inline void writeGenericValue(std::ostream & os, const std::string & value,
                              bool forceQuotes) {
   writeQuotedString(os, value, forceQuotes);
}

/*
 * Friend function: readGenericValue
 * Usage: readGenericValue(is, value);
 * -----------------------------------
 * Reads a generic value from the input stream.  If that value is a string,
 * this function uses readQuotedString to read the value.
 */

template <typename ValueType>
void readGenericValue(std::istream & is, ValueType & value) {
   is >> value;
}

template <>
inline void readGenericValue(std::istream & is, std::string & value) {
   readQuotedString(is, value);
}


#endif

strlib.c的代码如下:
  1. /* 
  2.  * File: strlib.cpp 
  3.  * ---------------- 
  4.  * This file implements the strlib.h interface. 
  5.  */  
  6.   
  7. #include <cctype>  
  8. #include <iostream>  
  9. #include <sstream>  
  10. #include "error.h"  
  11. #include "strlib.h"  
  12. using namespace std;  
  13.   
  14. /* Function prototypes */  
  15.   
  16. /* 
  17.  * Implementation notes: numeric conversion 
  18.  * ---------------------------------------- 
  19.  * These functions use the <sstream> library to perform the conversion. 
  20.  */  
  21.   
  22. string integerToString(int n) {  
  23.    ostringstream stream;  
  24.    stream << n;  
  25.    return stream.str();  
  26. }  
  27.   
  28. int stringToInteger(string str) {  
  29.    istringstream stream(str);  
  30.    int value;  
  31.    stream >> value >> ws;  
  32.    if (stream.fail() || !stream.eof()) {  
  33.       error("stringToInteger: Illegal integer format (" + str + ")");  
  34.    }  
  35.    return value;  
  36. }  
  37.   
  38. string realToString(double d) {  
  39.    ostringstream stream;  
  40.    stream << uppercase << d;  
  41.    return stream.str();  
  42. }  
  43.   
  44. double stringToReal(string str) {  
  45.    istringstream stream(str);  
  46.    double value;  
  47.    stream >> value >> ws;  
  48.    if (stream.fail() || !stream.eof()) {  
  49.       error("stringToReal: Illegal floating-point format (" + str + ")");  
  50.    }  
  51.    return value;  
  52. }  
  53.   
  54. /* 
  55.  * Implementation notes: case conversion 
  56.  * ------------------------------------- 
  57.  * The functions toUpperCase and toLowerCase return a new string whose 
  58.  * characters appear in the desired case. These implementations rely on 
  59.  * the fact that the characters in the string are copied when the 
  60.  * argument is passed to the function, which makes it possible to change 
  61.  * the case of the copy without affecting the original. 
  62.  */  
  63.   
  64. string toUpperCase(string str) {  
  65.    int nChars = str.length();  
  66.    for (int i = 0; i < nChars; i++) {  
  67.       str[i] = toupper(str[i]);  
  68.    }  
  69.    return str;  
  70. }  
  71.   
  72. string toLowerCase(string str) {  
  73.    int nChars = str.length();  
  74.    for (int i = 0; i < nChars; i++) {  
  75.       str[i] = tolower(str[i]);  
  76.    }  
  77.    return str;  
  78. }  
  79.   
  80. /* 
  81.  * Implementation notes: equalsIgnoreCase 
  82.  * -------------------------------------- 
  83.  * This implementation uses a for loop to cycle through the characters in 
  84.  * each string.  Converting each string to uppercase and then comparing 
  85.  * the results makes for a shorter but less efficient implementation. 
  86.  */  
  87.   
  88. bool equalsIgnoreCase(string s1, string s2) {  
  89.    if (s1.length() != s2.length()) return false;  
  90.    int nChars = s1.length();  
  91.    for (int i = 0; i < nChars; i++) {  
  92.       if (tolower(s1[i]) != tolower(s2[i])) return false;  
  93.    }  
  94.    return true;  
  95. }  
  96.   
  97. /* 
  98.  * Implementation notes: startsWith, endsWith 
  99.  * ------------------------------------------ 
  100.  * These implementations are overloaded to allow the second argument to 
  101.  * be either a string or a character. 
  102.  */  
  103.   
  104. bool startsWith(string str, string prefix) {  
  105.    if (str.length() < prefix.length()) return false;  
  106.    int nChars = prefix.length();  
  107.    for (int i = 0; i < nChars; i++) {  
  108.       if (str[i] != prefix[i]) return false;  
  109.    }  
  110.    return true;  
  111. }  
  112.   
  113. bool startsWith(string str, char prefix) {  
  114.    return str.length() > 0 && str[0] == prefix;  
  115. }  
  116.   
  117. bool endsWith(string str, string suffix) {  
  118.    int nChars = suffix.length();  
  119.    int start = str.length() - nChars;  
  120.    if (start < 0) return false;  
  121.    for (int i = 0; i < nChars; i++) {  
  122.       if (str[start + i] != suffix[i]) return false;  
  123.    }  
  124.    return true;  
  125. }  
  126.   
  127. bool endsWith(string str, char suffix) {  
  128.    return str.length() > 0 && str[str.length() - 1] == suffix;  
  129. }  
  130.   
  131. string trim(string str) {  
  132.    int finish = str.length() - 1;  
  133.    while (finish >= 0 && isspace(str[finish])) {  
  134.       finish--;  
  135.    }  
  136.    int start = 0;  
  137.    while (start <= finish && isspace(str[start])) {  
  138.       start++;  
  139.    }  
  140.    return str.substr(start, finish - start + 1);  
  141. }  
  142.   
  143. /* 
  144.  * Implementation notes: readQuotedString and writeQuotedString 
  145.  * ------------------------------------------------------------ 
  146.  * Most of the work in these functions has to do with escape sequences. 
  147.  */  
  148.   
  149. static const string STRING_DELIMITERS = ",:)}]\n";  
  150.   
  151. bool stringNeedsQuoting(const string & str) {  
  152.    int n = str.length();  
  153.    for (int i = 0; i < n; i++) {  
  154.       char ch = str[i];  
  155.       if (isspace(ch)) return false;  
  156.       if (STRING_DELIMITERS.find(ch) != string::npos) return true;  
  157.    }  
  158.    return false;  
  159. }  
  160.   
  161. void readQuotedString(istream & is, string & str) {  
  162.    str = "";  
  163.    char ch;  
  164.    while (is.get(ch) && isspace(ch)) {  
  165.       /* Empty */  
  166.    }  
  167.    if (is.fail()) return;  
  168.    if (ch == '\'' || ch == '"') {  
  169.       char delim = ch;  
  170.       while (is.get(ch) && ch != delim) {  
  171.          if (is.fail()) error("Unterminated string");  
  172.          if (ch == '\\') {  
  173.             if (!is.get(ch)) error("Unterminated string");  
  174.             if (isdigit(ch) || ch == 'x') {  
  175.                int base = 8;  
  176.                if (ch == 'x') base = 16;  
  177.                int result = 0;  
  178.                int digit = 0;  
  179.                while (ch != delim) {  
  180.                   if (isdigit(ch)) {  
  181.                      digit = ch - '0';  
  182.                   } else if (isalpha(ch)) {  
  183.                      digit = toupper(ch) - 'A' + 10;  
  184.                   } else {  
  185.                      digit = base;  
  186.                   }  
  187.                   if (digit >= base) break;  
  188.                   result = base * result + digit;  
  189.                   if (!is.get(ch)) error("Unterminated string");  
  190.                }  
  191.                ch = char(result);  
  192.                is.unget();  
  193.             } else {  
  194.                switch (ch) {  
  195.                 case 'a': ch = '\a'break;  
  196.                 case 'b': ch = '\b'break;  
  197.                 case 'f': ch = '\f'break;  
  198.                 case 'n': ch = '\n'break;  
  199.                 case 'r': ch = '\r'break;  
  200.                 case 't': ch = '\t'break;  
  201.                 case 'v': ch = '\v'break;  
  202.                 case '"': ch = '"'break;  
  203.                 case '\'': ch = '\''break;  
  204.                 case '\\': ch = '\\'; break;  
  205.                }  
  206.             }  
  207.          }  
  208.          str += ch;  
  209.       }  
  210.    } else {  
  211.       str += ch;  
  212.       int endTrim = 0;  
  213.       while (is.get(ch) && STRING_DELIMITERS.find(ch) == string::npos) {  
  214.          str += ch;  
  215.          if (!isspace(ch)) endTrim = str.length();  
  216.       }  
  217.       if (is) is.unget();  
  218.       str = str.substr(0, endTrim);  
  219.    }  
  220. }  
  221.   
  222. void writeQuotedString(ostream & os, const string & str, bool forceQuotes) {  
  223.    if (!forceQuotes && stringNeedsQuoting(str)) forceQuotes = true;  
  224.    if (forceQuotes) os << '"';  
  225.    int len = str.length();  
  226.    for (int i = 0; i < len; i++) {  
  227.       char ch = str.at(i);  
  228.       switch (ch) {  
  229.        case '\a': os << "\\a"break;  
  230.        case '\b': os << "\\b"break;  
  231.        case '\f': os << "\\f"break;  
  232.        case '\n': os << "\\n"break;  
  233.        case '\r': os << "\\r"break;  
  234.        case '\t': os << "\\t"break;  
  235.        case '\v': os << "\\v"break;  
  236.        case '"': os << oct << "\\" << (int(ch) & 0xFF); break;  
  237.        case '\\': os << "\\\\"break;  
  238.        default:  
  239.          if (isprint(ch)) {  
  240.             os << ch;  
  241.          } else {  
  242.             ostringstream oss;  
  243.             oss << oct << (int(ch) & 0xFF);  
  244.             os << "\\" << oss.str();  
  245.          }  
  246.       }  
  247.    }  
  248.    if (forceQuotes) os << '"';  
  249. }  
/*
 * File: strlib.cpp
 * ----------------
 * This file implements the strlib.h interface.
 */

#include <cctype>
#include <iostream>
#include <sstream>
#include "error.h"
#include "strlib.h"
using namespace std;

/* Function prototypes */

/*
 * Implementation notes: numeric conversion
 * ----------------------------------------
 * These functions use the <sstream> library to perform the conversion.
 */

string integerToString(int n) {
   ostringstream stream;
   stream << n;
   return stream.str();
}

int stringToInteger(string str) {
   istringstream stream(str);
   int value;
   stream >> value >> ws;
   if (stream.fail() || !stream.eof()) {
      error("stringToInteger: Illegal integer format (" + str + ")");
   }
   return value;
}

string realToString(double d) {
   ostringstream stream;
   stream << uppercase << d;
   return stream.str();
}

double stringToReal(string str) {
   istringstream stream(str);
   double value;
   stream >> value >> ws;
   if (stream.fail() || !stream.eof()) {
      error("stringToReal: Illegal floating-point format (" + str + ")");
   }
   return value;
}

/*
 * Implementation notes: case conversion
 * -------------------------------------
 * The functions toUpperCase and toLowerCase return a new string whose
 * characters appear in the desired case. These implementations rely on
 * the fact that the characters in the string are copied when the
 * argument is passed to the function, which makes it possible to change
 * the case of the copy without affecting the original.
 */

string toUpperCase(string str) {
   int nChars = str.length();
   for (int i = 0; i < nChars; i++) {
      str[i] = toupper(str[i]);
   }
   return str;
}

string toLowerCase(string str) {
   int nChars = str.length();
   for (int i = 0; i < nChars; i++) {
      str[i] = tolower(str[i]);
   }
   return str;
}

/*
 * Implementation notes: equalsIgnoreCase
 * --------------------------------------
 * This implementation uses a for loop to cycle through the characters in
 * each string.  Converting each string to uppercase and then comparing
 * the results makes for a shorter but less efficient implementation.
 */

bool equalsIgnoreCase(string s1, string s2) {
   if (s1.length() != s2.length()) return false;
   int nChars = s1.length();
   for (int i = 0; i < nChars; i++) {
      if (tolower(s1[i]) != tolower(s2[i])) return false;
   }
   return true;
}

/*
 * Implementation notes: startsWith, endsWith
 * ------------------------------------------
 * These implementations are overloaded to allow the second argument to
 * be either a string or a character.
 */

bool startsWith(string str, string prefix) {
   if (str.length() < prefix.length()) return false;
   int nChars = prefix.length();
   for (int i = 0; i < nChars; i++) {
      if (str[i] != prefix[i]) return false;
   }
   return true;
}

bool startsWith(string str, char prefix) {
   return str.length() > 0 && str[0] == prefix;
}

bool endsWith(string str, string suffix) {
   int nChars = suffix.length();
   int start = str.length() - nChars;
   if (start < 0) return false;
   for (int i = 0; i < nChars; i++) {
      if (str[start + i] != suffix[i]) return false;
   }
   return true;
}

bool endsWith(string str, char suffix) {
   return str.length() > 0 && str[str.length() - 1] == suffix;
}

string trim(string str) {
   int finish = str.length() - 1;
   while (finish >= 0 && isspace(str[finish])) {
      finish--;
   }
   int start = 0;
   while (start <= finish && isspace(str[start])) {
      start++;
   }
   return str.substr(start, finish - start + 1);
}

/*
 * Implementation notes: readQuotedString and writeQuotedString
 * ------------------------------------------------------------
 * Most of the work in these functions has to do with escape sequences.
 */

static const string STRING_DELIMITERS = ",:)}]\n";

bool stringNeedsQuoting(const string & str) {
   int n = str.length();
   for (int i = 0; i < n; i++) {
      char ch = str[i];
      if (isspace(ch)) return false;
      if (STRING_DELIMITERS.find(ch) != string::npos) return true;
   }
   return false;
}

void readQuotedString(istream & is, string & str) {
   str = "";
   char ch;
   while (is.get(ch) && isspace(ch)) {
      /* Empty */
   }
   if (is.fail()) return;
   if (ch == '\'' || ch == '"') {
      char delim = ch;
      while (is.get(ch) && ch != delim) {
         if (is.fail()) error("Unterminated string");
         if (ch == '\\') {
            if (!is.get(ch)) error("Unterminated string");
            if (isdigit(ch) || ch == 'x') {
               int base = 8;
               if (ch == 'x') base = 16;
               int result = 0;
               int digit = 0;
               while (ch != delim) {
                  if (isdigit(ch)) {
                     digit = ch - '0';
                  } else if (isalpha(ch)) {
                     digit = toupper(ch) - 'A' + 10;
                  } else {
                     digit = base;
                  }
                  if (digit >= base) break;
                  result = base * result + digit;
                  if (!is.get(ch)) error("Unterminated string");
               }
               ch = char(result);
               is.unget();
            } else {
               switch (ch) {
                case 'a': ch = '\a'; break;
                case 'b': ch = '\b'; break;
                case 'f': ch = '\f'; break;
                case 'n': ch = '\n'; break;
                case 'r': ch = '\r'; break;
                case 't': ch = '\t'; break;
                case 'v': ch = '\v'; break;
                case '"': ch = '"'; break;
                case '\'': ch = '\''; break;
                case '\\': ch = '\\'; break;
               }
            }
         }
         str += ch;
      }
   } else {
      str += ch;
      int endTrim = 0;
      while (is.get(ch) && STRING_DELIMITERS.find(ch) == string::npos) {
         str += ch;
         if (!isspace(ch)) endTrim = str.length();
      }
      if (is) is.unget();
      str = str.substr(0, endTrim);
   }
}

void writeQuotedString(ostream & os, const string & str, bool forceQuotes) {
   if (!forceQuotes && stringNeedsQuoting(str)) forceQuotes = true;
   if (forceQuotes) os << '"';
   int len = str.length();
   for (int i = 0; i < len; i++) {
      char ch = str.at(i);
      switch (ch) {
       case '\a': os << "\\a"; break;
       case '\b': os << "\\b"; break;
       case '\f': os << "\\f"; break;
       case '\n': os << "\\n"; break;
       case '\r': os << "\\r"; break;
       case '\t': os << "\\t"; break;
       case '\v': os << "\\v"; break;
       case '"': os << oct << "\\" << (int(ch) & 0xFF); break;
       case '\\': os << "\\\\"; break;
       default:
         if (isprint(ch)) {
            os << ch;
         } else {
            ostringstream oss;
            oss << oct << (int(ch) & 0xFF);
            os << "\\" << oss.str();
         }
      }
   }
   if (forceQuotes) os << '"';
}

在C++中,有两种类型的字符串:
  • C类型字符串,来自于C编程语言
  • C++类型string,C++实现的库
在C++中,尽可能的使用string类型。

对于string s = "Nubian " + "ibex";
这些字符串是C风格的,C风格的字符串是不支持+操作的,该表达式编译不通过。改为如下:
string s = string("Nubian ") + "ibex";
现在显式的转换C风格的字符串为C++类型的字符串,这样该代码是合法的。

二、字符串中的递归操作

1.对一个字符串进行逆序操作
递归的对字符串进行逆序操作,如下示意图所示:

代码实现如下:
  1. /* File: reverse.cpp 
  2.  * 
  3.  * Code to recursively reverse a string. 
  4.  */  
  5. #include <iostream>  
  6. #include <string>  
  7. #include "simpio.h"  
  8. using namespace std;  
  9.   
  10. string reverseString(string line);  
  11.   
  12. int main() {  
  13.     string line = getLine("Enter a string: ");  
  14.     cout << reverseString(line) << endl;  
  15. }  
  16.   
  17. /* Returns the reverse of the indicated string. */  
  18. string reverseString(string line) {  
  19.     /* If the string is empty, it's its own reverse */  
  20.     if (line == "") {  
  21.         return "";  
  22.     }  
  23.     /* Otherwise, reverse all but the first character, then tack 
  24.      * on the first character. 
  25.      */  
  26.     else {  
  27.         return reverseString(line.substr(1)) + line[0];  
  28.     }  
  29. }  
/* File: reverse.cpp
 *
 * Code to recursively reverse a string.
 */
#include <iostream>
#include <string>
#include "simpio.h"
using namespace std;

string reverseString(string line);

int main() {
	string line = getLine("Enter a string: ");
	cout << reverseString(line) << endl;
}

/* Returns the reverse of the indicated string. */
string reverseString(string line) {
	/* If the string is empty, it's its own reverse */
	if (line == "") {
		return "";
	}
	/* Otherwise, reverse all but the first character, then tack
	 * on the first character.
	 */
	else {
		return reverseString(line.substr(1)) + line[0];
	}
}

2.回文(palindrome)
回文就是给定的字符串是对称的。
递归的判断给定的字符串是否是回文,示意图如下:

代码实现如下:
  1. /* File: palindrome.cpp 
  2.  * 
  3.  * A program that reads a file of English words, then prints out all 
  4.  * the palindromic words. 
  5.  */  
  6. #include <iostream>  
  7. #include <string>  
  8. #include <fstream>  
  9. #include "simpio.h"  
  10. using namespace std;  
  11.   
  12. bool isPalindrome(string text);  
  13.   
  14. int main() {  
  15.     /* Open the file for reading.  We really should check whether 
  16.      * the file is open before proceeding. 
  17.      */  
  18.     string file = "dictionary.txt";  
  19.     ifstream input(file.c_str());  
  20.       
  21.     /* Read each line of the file and print out those that are palindromes. */  
  22.     string line;  
  23.     while (getline(input, line)) {  
  24.         if (isPalindrome(line)) {  
  25.             cout << line << endl;  
  26.         }  
  27.     }  
  28.       
  29.     return 0;  
  30. }  
  31.   
  32. /* Returns whether the given string is a palindrome. */  
  33. bool isPalindrome(string text) {  
  34.     /* All characters of length 0 or length 1 are guaranteed to 
  35.      * be palindromes. 
  36.      */  
  37.     if (text.length() <= 1) {  
  38.         return true;  
  39.     }  
  40.     /* If the first and last character of the string aren't the same, 
  41.      * the string cannot be a palindrome. 
  42.      */  
  43.     else if (text[0] != text[text.length() - 1]) {  
  44.         return false;  
  45.     }  
  46.     /* Otherwise, this string is a palindrome precisely when the middle 
  47.      * characters are a palindrome. 
  48.      */  
  49.     else {  
  50.         return isPalindrome(text.substr(1, text.length() - 2));  
  51.     }  
  52. }  
/* File: palindrome.cpp
 *
 * A program that reads a file of English words, then prints out all
 * the palindromic words.
 */
#include <iostream>
#include <string>
#include <fstream>
#include "simpio.h"
using namespace std;

bool isPalindrome(string text);

int main() {
	/* Open the file for reading.  We really should check whether
	 * the file is open before proceeding.
	 */
	string file = "dictionary.txt";
	ifstream input(file.c_str());
	
	/* Read each line of the file and print out those that are palindromes. */
	string line;
	while (getline(input, line)) {
		if (isPalindrome(line)) {
			cout << line << endl;
		}
	}
	
	return 0;
}

/* Returns whether the given string is a palindrome. */
bool isPalindrome(string text) {
	/* All characters of length 0 or length 1 are guaranteed to
	 * be palindromes.
	 */
	if (text.length() <= 1) {
		return true;
	}
	/* If the first and last character of the string aren't the same,
	 * the string cannot be a palindrome.
	 */
	else if (text[0] != text[text.length() - 1]) {
		return false;
	}
	/* Otherwise, this string is a palindrome precisely when the middle
	 * characters are a palindrome.
	 */
	else {
		return isPalindrome(text.substr(1, text.length() - 2));
	}
}

3.C++中从File中读取数据

既然我们知道了如何操作字符串了,那么我们开始从外部文件中读取数据来处理。
在C++中,文件读取使用ifstream类来进行处理。必须包含头文件#include <fstream>来使用ifstream。

1)逐行读取
ifstream类通过使用getline函数从文件中读取一行
  1. getline(file, str);  
getline(file, str);

典型的读取文件中各行的循环如下所示:
  1. string line;  
  2. while(getline(file, line))  
  3. {  
  4.     /* ...process line... */  
  5. }  
string line;
while(getline(file, line))
{
    /* ...process line... */
}

回文的实现代码使用了文件的读取。

读取格式化的数据
从文件中读取格式化的数据可以通过使用流提取操作符:file>>variable
可以读取任何原始类型和字符串
当读取字符串时,在换行符或空格处即停止。

典型的读取格式化数据循环如下:
  1. type val;  
  2. while(file >> val)  
  3. {  
  4.     /* ... process val... */  
  5. }  
type val;
while(file >> val)
{
    /* ... process val... */
}

4.C++中参数传递

在C++中,有两种方法传递一个参数给一个函数:
  • 传值方式:参数通过拷贝传给一个函数。void myFunction(int x);
  • 引用方式:传递给函数的变量在函数中是可以改变的。void myFunction(int &x)
举例:
  1. int main()  
  2. {  
  3.     int x = 10;  
  4.     int y = 20;  
  5.       
  6.     //here: x = 10, y = 20  
  7.     sum(x, y);  
  8.     //here: x = 10, y = 20  
  9.     swap(x, y);  
  10.     //here: x = 20, y = 10  
  11.     cout << x << " " << y << endl;  
  12.       
  13.     return 0;  
  14. }  
  15.   
  16. //Pass by reference  
  17. void swap(int &x, int &y)  
  18. {  
  19.     int temp = x;  
  20.     x = y;  
  21.     y = temp;  
  22. }  
  23.   
  24. //Pass by value  
  25. void printSum(int x, int y)  
  26. {  
  27.     x += y;  
  28.     cout << x << endl;  
  29. }  一、C++中字符串(String)


    字符串(String):就是(可能是空的)字符序列。

    C++中的字符串在概念上和Java中的字符串类似。




    C++字符串用string类型来表示。在使用string类型之前,必须在程序中包含如下头文件




    [cpp] view plaincopy
    01.#include <string>


    可以通过调用如下方法:



    [cpp] view plaincopy
    01.str.length()

    来获取字符串中字符的长度。



    可以通过如下方式来从一个字符串中读取一个字符




    [cpp] view plaincopy
    01.str[index]

    尽管字符串不是数组,但是上述语法是一个方便的语法方式。



    字符操作

    在C++中,头文件<cctype>包含各种有用的处理字符的函数,以下函数用来检查给定的类型是否是一个给定的字符

    isalpha, isdigit, isalnum, islower, isupper, isspace, ispunct.




    跟Java中字符串不同,C++中字符串是可变的,可以被修改。

    改变单个字符的方式:




    [cpp] view plaincopy
    01.str[index] = ch





    附加更多的文本方式:




    [cpp] view plaincopy
    01.str += text


    这些操作直接改变字符串本身,而不是对字符串的副本进行操作。



    在C++中,==操作符可以直接拿来用于字符串的比较




    [cpp] view plaincopy
    01.if(str1 == str2)
    02.{
    03. /* string match */
    04.}


    在一个字符串中查询其他一些字符,可以使用find,如果找不到,则返回string::npos,而不是-1。



    [cpp] view plaincopy
    01.if(str1.find(str2) != string::npos)
    02.{
    03. /* found str2 inside str1 */
    04.}


    通过调用substr方法从string中获取substring。
    substr方法需要知道substring的开始位置和长度(不是结束位置)




    [cpp] view plaincopy
    01.string allButFirstChar = str.substr(1);
    02.string lastFiveChars = str.substr(str.length() - 5, 5);




    与Java语言不同的时,在C++中,只能连接字符串和字符到其他的字符串中。




    在本课程中,提供了"strlib.h"库,让字符串操作更加容易




    [cpp] view plaincopy
    01.string s = "I like " + integerToString(137);

    strlib.h的代码如下:



    [cpp] view plaincopy
    01./*
    02. * File: strlib.h
    03. * --------------
    04. * This file exports several useful string functions that are not
    05. * included in the C++ string library.
    06. */
    07.
    08.#ifndef _strlib_h
    09.#define _strlib_h
    10.
    11.#include <iostream>
    12.#include <string>
    13.
    14./*
    15. * Function: integerToString
    16. * Usage: string s = integerToString(n);
    17. * -------------------------------------
    18. * Converts an integer into the corresponding string of digits.
    19. * For example, calling <code>integerToString(123)</code> returns
    20. * the string <code>"123"</code>.
    21. */
    22.
    23.std::string integerToString(int n);
    24.
    25./*
    26. * Function: stringToInteger
    27. * Usage: int n = stringToInteger(str);
    28. * ------------------------------------
    29. * Converts a string of digits into an integer. If the string is not a
    30. * legal integer or contains extraneous characters other than whitespace,
    31. * <code>stringToInteger</code> calls <code>error</code> with an
    32. * appropriate message.
    33. */
    34.
    35.int stringToInteger(std::string str);
    36.
    37./*
    38. * Function: realToString
    39. * Usage: string s = realToString(d);
    40. * ----------------------------------
    41. * Converts a floating-point number into the corresponding string form.
    42. * For example, calling <code>realToString(23.45)</code> returns
    43. * the string <code>"23.45"</code>.
    44. */
    45.
    46.std::string realToString(double d);
    47.
    48./*
    49. * Function: stringToReal
    50. * Usage: double d = stringToReal(str);
    51. * ------------------------------------
    52. * Converts a string representing a real number into its corresponding
    53. * value. If the string is not a legal floating-point number or contains
    54. * extraneous characters other than whitespace, <code>stringToReal</code>
    55. * calls <code>error</code> with an appropriate message.
    56. */
    57.
    58.double stringToReal(std::string str);
    59.
    60./*
    61. * Function: toUpperCase
    62. * Usage: string s = toUpperCase(str);
    63. * -----------------------------------
    64. * Returns a new string in which all lowercase characters have been converted
    65. * into their uppercase equivalents.
    66. */
    67.
    68.std::string toUpperCase(std::string str);
    69.
    70./*
    71. * Function: toLowerCase
    72. * Usage: string s = toLowerCase(str);
    73. * -----------------------------------
    74. * Returns a new string in which all uppercase characters have been converted
    75. * into their lowercase equivalents.
    76. */
    77.
    78.std::string toLowerCase(std::string str);
    79.
    80./*
    81. * Function: equalsIgnoreCase
    82. * Usage: if (equalsIgnoreCase(s1, s2)) ...
    83. * ----------------------------------------
    84. * Returns <code>true</code> if <code>s1</code> and <code>s2</code> are
    85. * equal discounting differences in case.
    86. */
    87.
    88.bool equalsIgnoreCase(std::string s1, std::string s2);
    89.
    90./*
    91. * Function: startsWith
    92. * Usage: if (startsWith(str, prefix)) ...
    93. * ---------------------------------------
    94. * Returns <code>true</code> if the string <code>str</code> starts with
    95. * the specified prefix, which may be either a string or a character.
    96. */
    97.
    98.bool startsWith(std::string str, std::string prefix);
    99.bool startsWith(std::string str, char prefix);
    100.
    101./*
    102. * Function: endsWith
    103. * Usage: if (endsWith(str, suffix)) ...
    104. * -------------------------------------
    105. * Returns <code>true</code> if the string <code>str</code> ends with
    106. * the specified suffix, which may be either a string or a character.
    107. */
    108.
    109.bool endsWith(std::string str, std::string suffix);
    110.bool endsWith(std::string str, char suffix);
    111.
    112./*
    113. * Function: trim
    114. * Usage: string trimmed = trim(str);
    115. * ----------------------------------
    116. * Returns a new string after removing any whitespace characters
    117. * from the beginning and end of the argument.
    118. */
    119.
    120.std::string trim(std::string str);
    121.
    122./* Private section */
    123.
    124./**********************************************************************/
    125./* Note: Everything below this point in the file is logically part */
    126./* of the implementation and should not be of interest to clients. */
    127./**********************************************************************/
    128.
    129./*
    130. * Friend function: writeQuotedString
    131. * Usage: writeQuotedString(outfile, str, forceQuotes);
    132. * ----------------------------------------------------
    133. * Writes the string str to outfile surrounded by double quotes, converting
    134. * special characters to escape sequences, as necessary. If the optional
    135. * parameter forceQuotes is explicitly set to false, quotes are included
    136. * in the output only if necessary.
    137. */
    138.
    139.void writeQuotedString(std::ostream & os, const std::string & str,
    140. bool forceQuotes = true);
    141.
    142./*
    143. * Friend function: readQuotedString
    144. * Usage: readQuotedString(infile, str);
    145. * -------------------------------------
    146. * Reads the next string from infile into the reference parameter str.
    147. * If the first character (other than whitespace) is either a single
    148. * or a double quote, this function reads characters up to the
    149. * matching quote, processing standard escape sequences as it goes.
    150. * If not, readString reads characters up to any of the characters
    151. * in the string STRING_DELIMITERS in the implementation file.
    152. */
    153.
    154.void readQuotedString(std::istream & is, std::string & str);
    155.
    156./*
    157. * Friend function: stringNeedsQuoting
    158. * Usage: if (stringNeedsQuoting(str)) ...
    159. * ---------------------------------------
    160. * Checks whether the string needs quoting in order to be read correctly.
    161. */
    162.
    163.bool stringNeedsQuoting(const std::string & str);
    164.
    165./*
    166. * Friend function: writeGenericValue
    167. * Usage: writeGenericValue(os, value, forceQuotes);
    168. * -------------------------------------------------
    169. * Writes a generic value to the output stream. If that value is a string,
    170. * this function uses writeQuotedString to write the value.
    171. */
    172.
    173.template <typename ValueType>
    174.void writeGenericValue(std::ostream & os, const ValueType & value,
    175. bool forceQuotes) {
    176. os << value;
    177.}
    178.
    179.template <>
    180.inline void writeGenericValue(std::ostream & os, const std::string & value,
    181. bool forceQuotes) {
    182. writeQuotedString(os, value, forceQuotes);
    183.}
    184.
    185./*
    186. * Friend function: readGenericValue
    187. * Usage: readGenericValue(is, value);
    188. * -----------------------------------
    189. * Reads a generic value from the input stream. If that value is a string,
    190. * this function uses readQuotedString to read the value.
    191. */
    192.
    193.template <typename ValueType>
    194.void readGenericValue(std::istream & is, ValueType & value) {
    195. is >> value;
    196.}
    197.
    198.template <>
    199.inline void readGenericValue(std::istream & is, std::string & value) {
    200. readQuotedString(is, value);
    201.}
    202.
    203.
    204.#endif


    strlib.c的代码如下:



    [cpp] view plaincopy
    01./*
    02. * File: strlib.cpp
    03. * ----------------
    04. * This file implements the strlib.h interface.
    05. */
    06.
    07.#include <cctype>
    08.#include <iostream>
    09.#include <sstream>
    10.#include "error.h"
    11.#include "strlib.h"
    12.using namespace std;
    13.
    14./* Function prototypes */
    15.
    16./*
    17. * Implementation notes: numeric conversion
    18. * ----------------------------------------
    19. * These functions use the <sstream> library to perform the conversion.
    20. */
    21.
    22.string integerToString(int n) {
    23. ostringstream stream;
    24. stream << n;
    25. return stream.str();
    26.}
    27.
    28.int stringToInteger(string str) {
    29. istringstream stream(str);
    30. int value;
    31. stream >> value >> ws;
    32. if (stream.fail() || !stream.eof()) {
    33. error("stringToInteger: Illegal integer format (" + str + ")");
    34. }
    35. return value;
    36.}
    37.
    38.string realToString(double d) {
    39. ostringstream stream;
    40. stream << uppercase << d;
    41. return stream.str();
    42.}
    43.
    44.double stringToReal(string str) {
    45. istringstream stream(str);
    46. double value;
    47. stream >> value >> ws;
    48. if (stream.fail() || !stream.eof()) {
    49. error("stringToReal: Illegal floating-point format (" + str + ")");
    50. }
    51. return value;
    52.}
    53.
    54./*
    55. * Implementation notes: case conversion
    56. * -------------------------------------
    57. * The functions toUpperCase and toLowerCase return a new string whose
    58. * characters appear in the desired case. These implementations rely on
    59. * the fact that the characters in the string are copied when the
    60. * argument is passed to the function, which makes it possible to change
    61. * the case of the copy without affecting the original.
    62. */
    63.
    64.string toUpperCase(string str) {
    65. int nChars = str.length();
    66. for (int i = 0; i < nChars; i++) {
    67. str[i] = toupper(str[i]);
    68. }
    69. return str;
    70.}
    71.
    72.string toLowerCase(string str) {
    73. int nChars = str.length();
    74. for (int i = 0; i < nChars; i++) {
    75. str[i] = tolower(str[i]);
    76. }
    77. return str;
    78.}
    79.
    80./*
    81. * Implementation notes: equalsIgnoreCase
    82. * --------------------------------------
    83. * This implementation uses a for loop to cycle through the characters in
    84. * each string. Converting each string to uppercase and then comparing
    85. * the results makes for a shorter but less efficient implementation.
    86. */
    87.
    88.bool equalsIgnoreCase(string s1, string s2) {
    89. if (s1.length() != s2.length()) return false;
    90. int nChars = s1.length();
    91. for (int i = 0; i < nChars; i++) {
    92. if (tolower(s1[i]) != tolower(s2[i])) return false;
    93. }
    94. return true;
    95.}
    96.
    97./*
    98. * Implementation notes: startsWith, endsWith
    99. * ------------------------------------------
    100. * These implementations are overloaded to allow the second argument to
    101. * be either a string or a character.
    102. */
    103.
    104.bool startsWith(string str, string prefix) {
    105. if (str.length() < prefix.length()) return false;
    106. int nChars = prefix.length();
    107. for (int i = 0; i < nChars; i++) {
    108. if (str[i] != prefix[i]) return false;
    109. }
    110. return true;
    111.}
    112.
    113.bool startsWith(string str, char prefix) {
    114. return str.length() > 0 && str[0] == prefix;
    115.}
    116.
    117.bool endsWith(string str, string suffix) {
    118. int nChars = suffix.length();
    119. int start = str.length() - nChars;
    120. if (start < 0) return false;
    121. for (int i = 0; i < nChars; i++) {
    122. if (str[start + i] != suffix[i]) return false;
    123. }
    124. return true;
    125.}
    126.
    127.bool endsWith(string str, char suffix) {
    128. return str.length() > 0 && str[str.length() - 1] == suffix;
    129.}
    130.
    131.string trim(string str) {
    132. int finish = str.length() - 1;
    133. while (finish >= 0 && isspace(str[finish])) {
    134. finish--;
    135. }
    136. int start = 0;
    137. while (start <= finish && isspace(str[start])) {
    138. start++;
    139. }
    140. return str.substr(start, finish - start + 1);
    141.}
    142.
    143./*
    144. * Implementation notes: readQuotedString and writeQuotedString
    145. * ------------------------------------------------------------
    146. * Most of the work in these functions has to do with escape sequences.
    147. */
    148.
    149.static const string STRING_DELIMITERS = ",:)}]\n";
    150.
    151.bool stringNeedsQuoting(const string & str) {
    152. int n = str.length();
    153. for (int i = 0; i < n; i++) {
    154. char ch = str[i];
    155. if (isspace(ch)) return false;
    156. if (STRING_DELIMITERS.find(ch) != string::npos) return true;
    157. }
    158. return false;
    159.}
    160.
    161.void readQuotedString(istream & is, string & str) {
    162. str = "";
    163. char ch;
    164. while (is.get(ch) && isspace(ch)) {
    165. /* Empty */
    166. }
    167. if (is.fail()) return;
    168. if (ch == '\'' || ch == '"') {
    169. char delim = ch;
    170. while (is.get(ch) && ch != delim) {
    171. if (is.fail()) error("Unterminated string");
    172. if (ch == '\\') {
    173. if (!is.get(ch)) error("Unterminated string");
    174. if (isdigit(ch) || ch == 'x') {
    175. int base = 8;
    176. if (ch == 'x') base = 16;
    177. int result = 0;
    178. int digit = 0;
    179. while (ch != delim) {
    180. if (isdigit(ch)) {
    181. digit = ch - '0';
    182. } else if (isalpha(ch)) {
    183. digit = toupper(ch) - 'A' + 10;
    184. } else {
    185. digit = base;
    186. }
    187. if (digit >= base) break;
    188. result = base * result + digit;
    189. if (!is.get(ch)) error("Unterminated string");
    190. }
    191. ch = char(result);
    192. is.unget();
    193. } else {
    194. switch (ch) {
    195. case 'a': ch = '\a'; break;
    196. case 'b': ch = '\b'; break;
    197. case 'f': ch = '\f'; break;
    198. case 'n': ch = '\n'; break;
    199. case 'r': ch = '\r'; break;
    200. case 't': ch = '\t'; break;
    201. case 'v': ch = '\v'; break;
    202. case '"': ch = '"'; break;
    203. case '\'': ch = '\''; break;
    204. case '\\': ch = '\\'; break;
    205. }
    206. }
    207. }
    208. str += ch;
    209. }
    210. } else {
    211. str += ch;
    212. int endTrim = 0;
    213. while (is.get(ch) && STRING_DELIMITERS.find(ch) == string::npos) {
    214. str += ch;
    215. if (!isspace(ch)) endTrim = str.length();
    216. }
    217. if (is) is.unget();
    218. str = str.substr(0, endTrim);
    219. }
    220.}
    221.
    222.void writeQuotedString(ostream & os, const string & str, bool forceQuotes) {
    223. if (!forceQuotes && stringNeedsQuoting(str)) forceQuotes = true;
    224. if (forceQuotes) os << '"';
    225. int len = str.length();
    226. for (int i = 0; i < len; i++) {
    227. char ch = str.at(i);
    228. switch (ch) {
    229. case '\a': os << "\\a"; break;
    230. case '\b': os << "\\b"; break;
    231. case '\f': os << "\\f"; break;
    232. case '\n': os << "\\n"; break;
    233. case '\r': os << "\\r"; break;
    234. case '\t': os << "\\t"; break;
    235. case '\v': os << "\\v"; break;
    236. case '"': os << oct << "\\" << (int(ch) & 0xFF); break;
    237. case '\\': os << "\\\\"; break;
    238. default:
    239. if (isprint(ch)) {
    240. os << ch;
    241. } else {
    242. ostringstream oss;
    243. oss << oct << (int(ch) & 0xFF);
    244. os << "\\" << oss.str();
    245. }
    246. }
    247. }
    248. if (forceQuotes) os << '"';
    249.}


    在C++中,有两种类型的字符串:
    •C类型字符串,来自于C编程语言
    •C++类型string,C++实现的库

    在C++中,尽可能的使用string类型。




    对于string s = "Nubian " + "ibex";

    这些字符串是C风格的,C风格的字符串是不支持+操作的,该表达式编译不通过。改为如下:

    string s = string("Nubian ") + "ibex";

    现在显式的转换C风格的字符串为C++类型的字符串,这样该代码是合法的。



    二、字符串中的递归操作

    1.对一个字符串进行逆序操作
    递归的对字符串进行逆序操作,如下示意图所示:




    代码实现如下:




    [cpp] view plaincopy
    01./* File: reverse.cpp
    02. *
    03. * Code to recursively reverse a string.
    04. */
    05.#include <iostream>
    06.#include <string>
    07.#include "simpio.h"
    08.using namespace std;
    09.
    10.string reverseString(string line);
    11.
    12.int main() {
    13. string line = getLine("Enter a string: ");
    14. cout << reverseString(line) << endl;
    15.}
    16.
    17./* Returns the reverse of the indicated string. */
    18.string reverseString(string line) {
    19. /* If the string is empty, it's its own reverse */
    20. if (line == "") {
    21. return "";
    22. }
    23. /* Otherwise, reverse all but the first character, then tack
    24. * on the first character.
    25. */
    26. else {
    27. return reverseString(line.substr(1)) + line[0];
    28. }
    29.}


    2.回文(palindrome)
    回文就是给定的字符串是对称的。

    递归的判断给定的字符串是否是回文,示意图如下:




    代码实现如下:




    [cpp] view plaincopy
    01./* File: palindrome.cpp
    02. *
    03. * A program that reads a file of English words, then prints out all
    04. * the palindromic words.
    05. */
    06.#include <iostream>
    07.#include <string>
    08.#include <fstream>
    09.#include "simpio.h"
    10.using namespace std;
    11.
    12.bool isPalindrome(string text);
    13.
    14.int main() {
    15. /* Open the file for reading. We really should check whether
    16. * the file is open before proceeding.
    17. */
    18. string file = "dictionary.txt";
    19. ifstream input(file.c_str());
    20.
    21. /* Read each line of the file and print out those that are palindromes. */
    22. string line;
    23. while (getline(input, line)) {
    24. if (isPalindrome(line)) {
    25. cout << line << endl;
    26. }
    27. }
    28.
    29. return 0;
    30.}
    31.
    32./* Returns whether the given string is a palindrome. */
    33.bool isPalindrome(string text) {
    34. /* All characters of length 0 or length 1 are guaranteed to
    35. * be palindromes.
    36. */
    37. if (text.length() <= 1) {
    38. return true;
    39. }
    40. /* If the first and last character of the string aren't the same,
    41. * the string cannot be a palindrome.
    42. */
    43. else if (text[0] != text[text.length() - 1]) {
    44. return false;
    45. }
    46. /* Otherwise, this string is a palindrome precisely when the middle
    47. * characters are a palindrome.
    48. */
    49. else {
    50. return isPalindrome(text.substr(1, text.length() - 2));
    51. }
    52.}


    3.C++中从File中读取数据

    既然我们知道了如何操作字符串了,那么我们开始从外部文件中读取数据来处理。

    在C++中,文件读取使用ifstream类来进行处理。必须包含头文件#include <fstream>来使用ifstream。




    1)逐行读取

    ifstream类通过使用getline函数从文件中读取一行




    [cpp] view plaincopy
    01.getline(file, str);


    典型的读取文件中各行的循环如下所示:



    [cpp] view plaincopy
    01.string line;
    02.while(getline(file, line))
    03.{
    04. /* ...process line... */
    05.}


    回文的实现代码使用了文件的读取。



    读取格式化的数据

    从文件中读取格式化的数据可以通过使用流提取操作符:file>>variable

    可以读取任何原始类型和字符串

    当读取字符串时,在换行符或空格处即停止。




    典型的读取格式化数据循环如下:




    [cpp] view plaincopy
    01.type val;
    02.while(file >> val)
    03.{
    04. /* ... process val... */
    05.}


    4.C++中参数传递

    在C++中,有两种方法传递一个参数给一个函数:

    •传值方式:参数通过拷贝传给一个函数。void myFunction(int x);
    •引用方式:传递给函数的变量在函数中是可以改变的。void myFunction(int &x)

    举例:




    [cpp] view plaincopy
    01.int main()
    02.{
    03. int x = 10;
    04. int y = 20;
    05.
    06. //here: x = 10, y = 20
    07. sum(x, y);
    08. //here: x = 10, y = 20
    09. swap(x, y);
    10. //here: x = 20, y = 10
    11. cout << x << " " << y << endl;
    12.
    13. return 0;
    14.}
    15.
    16.//Pass by reference
    17.void swap(int &x, int &y)
    18.{
    19. int temp = x;
    20. x = y;
    21. y = temp;
    22.}
    23.
    24.//Pass by value
    25.void printSum(int x, int y)
    26.{
    27. x += y;
    28. cout << x << endl;
    29.}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值