博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【stanford C++】字符串(String)与流(Stream)
阅读量:5272 次
发布时间:2019-06-14

本文共 16908 字,大约阅读时间需要 56 分钟。

字符串(String)与流(Stream)
一、C++中字符串(String)

字符串(String):就是(可能是空的)字符序列。
C++中的字符串在概念上和Java中的字符串类似。
C++字符串用string类型来表示。在使用string类型之前,必须在程序中包含如下头文件
#include 
可以通过调用如下方法:
str.length()
来获取字符串中字符的长度。
可以通过如下方式来从一个字符串中读取一个字符
str[index]
尽管字符串不是数组,但是上述语法是一个方便的语法方式。
字符操作
在C++中,头文件<cctype>包含各种有用的处理字符的函数,以下函数用来检查给定的类型是否是一个给定的字符
isalpha, isdigit, isalnum, islower, isupper, isspace, ispunct.
跟Java中字符串不同,C++中字符串是可变的,可以被修改。
改变单个字符的方式:
str[index] = ch
附加更多的文本方式:
str += text
这些操作直接改变字符串本身,而不是对字符串的副本进行操作。
在C++中,==操作符可以直接拿来用于字符串的比较
if(str1 == str2){    /* string match */}
在一个字符串中查询其他一些字符,可以使用find,如果找不到,则返回string::npos,而不是-1。
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);
与Java语言不同的时,在C++中,只能连接字符串和字符到其他的字符串中。
在本课程中,提供了"strlib.h"库,让字符串操作更加容易
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 
#include
/* * Function: integerToString * Usage: string s = integerToString(n); * ------------------------------------- * Converts an integer into the corresponding string of digits. * For example, calling
integerToString(123) returns * the string
"123". */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, *
stringToInteger calls
error 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
realToString(23.45) returns * the string
"23.45". */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,
stringToReal * calls
error 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
true if
s1 and
s2 are * equal discounting differences in case. */bool equalsIgnoreCase(std::string s1, std::string s2);/* * Function: startsWith * Usage: if (startsWith(str, prefix)) ... * --------------------------------------- * Returns
true if the string
str 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
true if the string
str 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
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
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 
#include
#include
#include "error.h"#include "strlib.h"using namespace std;/* Function prototypes *//* * Implementation notes: numeric conversion * ---------------------------------------- * These functions use the
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 
#include
#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 
#include
#include
#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);
典型的读取文件中各行的循环如下所示:
string line;while(getline(file, line)){    /* ...process line... */}
回文的实现代码使用了文件的读取。
读取格式化的数据
从文件中读取格式化的数据可以通过使用流提取操作符:file>>variable
可以读取任何原始类型和字符串
当读取字符串时,在换行符或空格处即停止。
典型的读取格式化数据循环如下:
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 referencevoid swap(int &x, int &y){	int temp = x;	x = y;	y = temp;}//Pass by valuevoid printSum(int x, int y){	x += y;	cout << x << endl;}

 

转载于:https://www.cnblogs.com/jiangu66/p/3170332.html

你可能感兴趣的文章
生成随机数的模板
查看>>
Mysql 数据库操作
查看>>
转:linux终端常用快捷键
查看>>
UVa 11059 最大乘积
查看>>
数组分割问题求两个子数组的和差值的小
查看>>
composer 报 zlib_decode(): data error
查看>>
linux下WPS的使用
查看>>
hdu 3938 并查集
查看>>
《深入分析Java Web技术内幕》读书笔记之JVM内存管理
查看>>
python之GIL release (I/O open(file) socket time.sleep)
查看>>
2015/8/4 告别飞思卡尔,抛下包袱上路
查看>>
软件开发与模型
查看>>
161017、SQL必备知识点
查看>>
kill新号专题
查看>>
MVC学习系列——Model验证扩展
查看>>
mysqladmin 修改和 初始化密码
查看>>
字符串
查看>>
vue2.x directive - 限制input只能输入正整数
查看>>
实现MyLinkedList类深入理解LinkedList
查看>>
自定义返回模型
查看>>