一、C++中字符串(String)
字符串(String):就是(可能是空的)字符序列。
C++中的字符串在概念上和Java中的字符串类似。
C++字符串用string类型来表示。在使用string类型之前,必须在程序中包含如下头文件
- #include <string>
#include <string>
可以通过调用如下方法:
- str.length()
str.length()
来获取字符串中字符的长度。
可以通过如下方式来从一个字符串中读取一个字符
- str[index]
str[index]
尽管字符串不是数组,但是上述语法是一个方便的语法方式。
字符操作
在C++中,头文件<cctype>包含各种有用的处理字符的函数,以下函数用来检查给定的类型是否是一个给定的字符
isalpha, isdigit, isalnum, islower, isupper, isspace, ispunct.
跟Java中字符串不同,C++中字符串是可变的,可以被修改。
改变单个字符的方式:
- str[index] = ch
str[index] = ch
附加更多的文本方式:
- str += text
str += text
这些操作直接改变字符串本身,而不是对字符串的副本进行操作。
在C++中,==操作符可以直接拿来用于字符串的比较
- if(str1 == str2)
- {
- /* string match */
- }
if(str1 == str2)
{
/* string match */
}
在一个字符串中查询其他一些字符,可以使用find,如果找不到,则返回string::npos,而不是-1。
- if(str1.find(str2) != string::npos)
- {
- /* found str2 inside str1 */
- }
if(str1.find(str2) != string::npos)
{
/* found str2 inside str1 */
}
通过调用substr方法从string中获取substring。
substr方法需要知道substring的开始位置和长度(不是结束位置)
- string allButFirstChar = str.substr(1);
- 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.}
,让字符串操作更加容易
字符串(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.}
,让字符串操作更加容易
- string s = "I like " + integerToString(137);
string s = "I like " + integerToString(137);
strlib.h的代码如下:
- /*
- * 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
/*
* 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的代码如下:
- /*
- * 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 << '"';
- }
/*
* 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.对一个字符串进行逆序操作
递归的对字符串进行逆序操作,如下示意图所示:
代码实现如下:
- /* 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];
- }
- }
/* 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)
回文就是给定的字符串是对称的。
递归的判断给定的字符串是否是回文,示意图如下:
代码实现如下:
- /* 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));
- }
- }
/* 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函数从文件中读取一行
- getline(file, str);
getline(file, str);
典型的读取文件中各行的循环如下所示:
- string line;
- while(getline(file, line))
- {
- /* ...process line... */
- }
string line;
while(getline(file, line))
{
/* ...process line... */
}
回文的实现代码使用了文件的读取。
读取格式化的数据
从文件中读取格式化的数据可以通过使用流提取操作符:file>>variable
可以读取任何原始类型和字符串
当读取字符串时,在换行符或空格处即停止。
典型的读取格式化数据循环如下:
- type val;
- while(file >> val)
- {
- /* ... process val... */
- }
type val;
while(file >> val)
{
/* ... process val... */
}
4.C++中参数传递
在C++中,有两种方法传递一个参数给一个函数:
- 传值方式:参数通过拷贝传给一个函数。void myFunction(int x);
- 引用方式:传递给函数的变量在函数中是可以改变的。void myFunction(int &x)
举例:
- int main()
- {
- int x = 10;
- int y = 20;
- //here: x = 10, y = 20
- sum(x, y);
- //here: x = 10, y = 20
- swap(x, y);
- //here: x = 20, y = 10
- cout << x << " " << y << endl;
- return 0;
- }
- //Pass by reference
- void swap(int &x, int &y)
- {
- int temp = x;
- x = y;
- y = temp;
- }
- //Pass by value
- void printSum(int x, int y)
- {
- x += y;
- cout << x << endl;
- } 一、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.}