C/C++中字符串String及字符操作方法 字符串的输入方法 String的操作方法 cctype Functions 字符串操作 样例 其它

本文总结C/C++中字符串操作方法,还在学习中,不定期更新。

。。

1、单个单词能够直接用std::cin,由于:std::cin读取并忽略开头全部的空白字符(如空格,换行符,制表符)。读取字符直至再次遇到空白字符,读取终止。

所以cin仅仅能读取单个单词。显然能够多次使用cin来获取多个单词;

2、多个单词使用函数std::getline(std::cin, s)请看以下代码:

#include <iostream>
#include <string> 
int main()
{
	std::string line; // empty string
	while(std::getline(std::cin, line))
	{
            // read line at time until end-of-file
	    std::cout << line << std::endl; // write s to the output
	}
    return 0;
}
Name: getline

这个函数接受两个參数:一个输入流对象和一个 string 对象。getline 函数从输入流的下一行读取,并保存读取的内容到不包含换行符。和输入操作符不一样的是,getline 并不忽略行开头的换行符。仅仅要 getline 遇到换行符,即便它是输入的第一个字符,getline 也将停止读入并返回。假设第一个字符就是换行符,则 string 參数将被置为空 string。

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

Prototype: ssize_t getline (char **lineptr, size_t *n, FILE *stream)
Description:
This function reads an entire line from stream, storing the text (including the newline and a terminating null character) in a buffer and storing the buffer address in *lineptr. 
Before calling getline, you should place in *lineptr the address of a buffer *n bytes long, allocated  with malloc. If this buffer is long enough to hold the line, getline stores the line in this buffer.  Otherwise, getline makes the buffer bigger using realloc, storing the new buffer address back in  *lineptr and the increased size back in *n. . 
If you set *lineptr to a null pointer, and *n to zero, before the call, then getline allocates the initial buffer for you by calling malloc. 
In either case, when getline returns, *lineptr is a char * which points to the text of the line. 
When getline is successful, it returns the number of characters read (including the newline, but  not including the terminating null). This value enables you to distinguish null characters that are  part of the line from the null character inserted as a terminator. 
This function is a GNU extension, but it is the recommended way to read lines from a stream. The  alternative standard functions are unreliable. 
If an error occurs or end of file is reached without any bytes read, getline returns -1. Header files:stdio.h

String的操作方法

s.empty()

Returns true if s is empty; otherwise returns false
假设 s 为空串,则返回 true,否则返回 false。


s.size()

Returns number of characters in s
返回 s 中字符的个数

s[n]

Returns the character at position n in s; positions start at 0.
返回 s 中位置为 n 的字符,位置从 0 開始计数

【注意:1、引用下标时假设超出下标作用范围就会引起溢出错误。相同不会报错。2、索引的实际数据类型是类型 unsigned 类型string::size_type。

#include <iostream>
#include <string>

int main()
{
	std::string s = "hello world";
	std::cout<<s<<std::endl;
	for (std::string::size_type ix = 0; ix != s.size(); ++ix)
	s[ix] = '*';
    std::cout<<"Now s is:"<<s<<std::endl;
    std::cout<<"s's len is:"<<s.size()<<", s[12]="<<s[100]<<std::endl;
    return 0;
}
注意:循环中使用了std::string::size_type ix = 0;请使用string内置类型size_type来操作。由于int型可能不够string的长度,所以内置类型size_type(实际能够觉得是unsigned)被创建,保证各机器的兼容性,避免溢出(和下标溢出可不是一回事)

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

s1 + s2

Returns a string equal to the concatenation of s1 and s2
把 s1 和s2 连接成一个新字符串,返回新生成的字符串

【备注: 能够连续加,和Python类似。

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

注意:当进行 string 对象和字符串字面值混合连接操作时,+ 操作符的左右操作数必须至少有一个是 string 类型的【想象下级联也就知道这确实是有道理的】。----1、也就是说+连接必须保证前两个有一个为string类型!2、字符串字面值不能直接相加,字符串字面值和string是不同类型的,字符串里面没有空字符' '。(更新于2014.06.24)

s1 = s2

Replaces characters in s1 by a copy of s2
把 s1 内容替换为 s2 的副本

【备注:。它必须先把 s1 占用的相关内存释放掉,然后再分配给 s2 足够存放 s2 副本的内存空间,最后把 s2 中的全部字符拷贝到新分配的内存空间。


v1 == v2

Returns true if v1 and v2 are equal; false otherwise
比較 v1 与 v2 的内容,相等则返回 true,否则返回 false

!=, <, <=, >, and >=

Have their normal meanings
保持这些操作符惯有的含义

cctype Functions

我们常常要对 string 对象中的单个字符进行处理,比如。通常须要知道某个特殊字符是否为空白字符、字母或数字。下面 列出了各种字符操作函数。适用于 string 对象的字符(或其它不论什么 char 值)。这些函数都在cctype 头文件里定义。

isalnum(c)

True if c is a letter or a digit.假设 c 是字母或数字,则为 True。

isalpha(c)

true if c is a letter.假设 c 是字母,则为 true。

iscntrl(c)

true if c is a control character.假设 c 是控制字符。则为 true

isdigit(c)

true if c is a digit.假设 c 是数字,则为 true。

isgraph(c)

true if c is not a space but is printable.假设 c 不是空格,但可打印,则为 true。


islower(c)

true if c is a lowercase letter.假设 c 是小写字母,则为 true。

isprint(c)

True if c is a printable character.假设 c 是可打印的字符,则为 true。

【注意:可打印的字符是指那些能够表示的字符】

ispunct(c)

True if c is a punctuation character.假设 c 是标点符号,则 true。

【注意:标点符号则是除了数字、字母或(可打印的)空白字符(如空格)以外的其它可打印字符】

isspace(c)

true if c is whitespace.假设 c 是空白字符。则为 true。

【注意:空白字符则是空格、制表符、垂直制表符、回车符、换行符和进纸符中的随意一种】

isupper(c)

True if c is an uppercase letter.假设 c 是大写字母。则 true。

isxdigit(c) 

true if c is a hexadecimal digit.假设是 c 十六进制数,则为 true。

tolower(c) 

If c is an uppercase letter, returns its lowercase equivalent; otherwise returns c unchanged.假设 c 大写字母。返回其小写字母形式,否则直接返回 c。


toupper(c)

If c is a lowercase letter, returns its uppercase equivalent; otherwise returns c unchanged.假设 c 是小写字母,则返回其大写字母形式。否则直接返回 c。


【注意:ctype.h是定义在C标准库中的头文件。cctype 事实上就是利用了 C 标准库函数。C 标准库头文件命名形式为 name 而 C++ 版本号则命名为 cname ,少了后缀,.h而在头文件名称前加了 c 表示这个头文件源自 C 标准库。因此,cctype 与 ctype.h 文件的内容是一样的,仅仅是採用了更适合 C++程序的形式特别地,cname 头文件里定义的名字都定义在命名空间 std 内,而 .h 版本号中的名字却不是这样。通常。C++ 程序中应採用 cname 这样的头文件的版本号,而不採用 name.h 版本号,这样。标准库中的名字在命名空间 std 中保持一致。

使用 .h 版本号会给程序猿带来负担,由于他们必须记得哪些标准库名字是从 C 继承来的,而哪些是 C++ 所特有的。

字符串操作

下面总结更新于2014.10.01,来源于经典教材。


当中:s和str是字符串string,ca是一个字符数组,str_ca是一个字符串或者一个字符数组,str_ca_ch是一个字符串、字符数组或一个字符,ch是一个字符。n、n1、n2、pos1、pos2是整数。

长度操作

s.capacity()

返回s获取的存储容量;

s.size()/s.length()

返回s的长度;

s.empty()

假设s没有包括字符则返回true。否则返回false;

s.max_size()

返回s可能的最大长度; 

编辑操作

s.append(str_ca)

将str_ca加入到s的结尾,返回s;

s.append(ca, n)

将ca的前n个字符加入到s的结尾,返回s;

s.append(n, ch)

将ch的n份拷贝加入到s的结尾,返回s;

s.insert(pos, str)

将str的拷贝插入到s的pos位置,返回s。

s.insert(pos1, str, pos2, n)

将str中从pos2位置開始的n个字符插入到s的pos1位置。返回s。【假设n大于str的长度。不会有问题。没有溢出错误。仅仅会拷贝到str的末尾】

s.insert(pos, ca, n)

将ca的前n个字符插入到s的pos位置,假设n被省略,则插入ca中全部的字符到pos位置,返回s;

s.insert(pos, n, ch)

将字符ch的n个拷贝插入到s的pos位置。返回s;

s.erase(pos, n)

删除s中从pos開始的n个字符(默认pos为0),返回s;

s.replace(pos1, n1, str)

将s中pos1位置開始的长度为n1的字符串替换为str【假设n1太大,从pos到s结尾的全部字符将被替换】。返回s;

s.replace(pos1, n1, ca, n2)

和上面一样,仅仅只是取ca的前n2个字符。返回s;

s.swap(str)/swap(s, str)

交换s和str的内容分。返回为void。

复制操作

支持+  +=操作符。

s.assign(str_ca)

将str_ca的一份拷贝赋予s。返回s。

s.assign(ca, n)

将ca的前n个字符构成的字符串赋予s。返回s;

s.assign(n, ch)

将n个ch组成的字符串赋予s,返回s;

s.substr(pos, n)

返回s中从pos(默觉得0)開始的,有n个字符组成的s的子串的拷贝。

查找操作

s.find(str_ca_ch, pos)

返回s中第一个大于等于pos的位置,而且从这个位置的下一个字符開始s中字符和str_ca_ch中对应字符匹配。假设没有这种位置则返回npos。pos默觉得0

s.find_first_of(str_ca_ch, pos)

返回s中大于等于pos的第一个和str_ca_ch中随意字符匹配的字符的位置,假设没有这种位置则返回npos,pos的默认值为0

s.find_first_not_of(str_ca_ch, pos)

返回s中大于等于pos的第一个和str_ca_ch中随意字符都不匹配的字符的位置,假设没有这种位置则返回npos。pos的默认值为0

s.find_last_of(str_ca_ch, pos)

返回s中小于等于pos的最大的一个和str_ca_ch中随意字符匹配的字符的位置,假设没有这种位置则返回npos,pos的默认值为0

s.find_last_not(str_ca_ch, pos)

返回s中小于等于pos的最大的一个和str_ca_ch中随意字符都不匹配的字符的位置,假设没有这种位置则返回npos,pos的默认值为0

s.rfind(str_ca_ch, pos)

返回s中最后一个小于等于pos的位置,而且从这个位置開始的str_ca_ch.size()个字符和str_ca_ch中对应的字符匹配。假设没有这种位置则返回npos。pos默觉得npos

比較操作

支持上述 <、<=、>、>=、==、!=操作符。

s.compare(str_ca)

返回值为正、0、负

string和C风格字符串的转换

s.c_str()

返回一个常字符数组。这个数组包括存储在s中字符。以一个空字符结束;

s.data()

返回一个常字符数组。这个数组包括存储在s中字符,但没有以空字符结束。

s.copy(charArray, pos, n)

将charArray替换为s中从pos開始的n个字符,假设pos被省略了,即从0開始,假设n太大。那么拷贝字符直到s结束,返回终于拷贝的字符个数。

备注:data()和c_str()都能够被用来从一个文件名称中提取open操作所须要的字符数组,此部分内容可能会在兴许文件操作中接触到。

样例

【此小节更新于2014.06.24】

原题在还有一篇博文中:C/C++中容器vector用法http://blog.csdn.net/zhanh1218/article/details/33323111

#include <iostream>
#include <string>
#include <vector>
using std::cin; using std::cout; using std::endl; using std::string; using std::vector;

string deal_word(string word)
{
	// 使用c++11 auto 语句 以及range for 语句
	for(auto &c : word)
	{
		if (not ispunct(c))
		{
			c = toupper(c); //连接非标点字符到字符串
		}
		else
		{
			word.erase(word.size()-1, 1); //仅仅能删除最后一个标点符号。

有局限性!

} } return word; } string deal_word2(string word) { // 使用下标及c++11 decltype for (decltype(word.size()) index = 0; index != word.size(); ++index) { if (not ispunct(word[index])) { word[index] = toupper(word[index]); } else { word.erase(index, 1); // 删除指定位置上的某一个字符。在此为标点 index -= 1; //保证下标不越界!

重要!

} } return word; } int main() { string word; // 缓存输入的单词 vector<string> text; // empty vector cout<<"Please input the text:"<<endl; //提示输入 while (std::cin >> word and word != "INPUTOVER") // INPUTOVER 用于标示输入结束,也能够ctrl + z停止输入 { word = deal_word(word); // 单词处理 text.push_back(word); // append word to text } for(std::vector<int>::size_type ix =0, j = 0; ix != text.size(); ++ix, ++j) { if (j==8) // 8个单词一行 { cout<<endl; //换行 j = 0; //又一次计数 } cout<<text[ix]<<" "; //加空格。 } return 0; }

改写了两种处理单词的方法。

使用了c++11中的新特性!

【更新于2014.06.05,一直忽视了for循环中不要增删迭代器中内容的问题。这个确实不优点理,还是选择复制吧(也就是原来的方法)!

错误概率低,可读性强。效率上还有待考证。

待补充。。。】

其它

str.erase()方法:来自百度

1、erase(pos, n); 删除从pos開始的n个字符。比方erase(0,1)就是删除第一个字符
2、erase(position); 删除position处的一个字符(position是个string类型的迭代器)
3、erase(first, last); 删除从first到last之间的字符(first和last都是迭代器)


本文由@The_Third_Wave(Blog地址:http://blog.csdn.net/zhanh1218)原创。

不定期更新。有错误请指正。

假设你看到这篇博文时发现不完整,那是我为防止爬虫先公布一半的原因。请看原作者Blog。

假设这篇博文对您有帮助,为了好的网络环境。不建议转载,建议收藏!

假设您一定要转载,请带上后缀和本文地址。