C++ 字符串
C++ 提供了以下两种类型的字符串表示形式:
- C 风格字符串
- C++ 引入的 string 类类型
C 风格字符串
C 风格的字符串起源于 C 语言,并在 C++ 中继续得到支持。字符串实际上是使用 null 字符 '\0' 终止的一维字符数组。因此,一个以 null 结尾的字符串,包含了组成字符串的字符。
下面的声明和初始化创建了一个 "Hello" 字符串。由于在数组的末尾存储了空字符,所以字符数组的大小比单词 "Hello" 的字符数多一个。
char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
依据数组初始化规则,您可以把上面的语句写成以下语句:
char greeting[] = "Hello";
以下是 C/C++ 中定义的字符串的内存表示:
其实,您不需要把 null 字符放在字符串常量的末尾。C++ 编译器会在初始化数组时,自动把 '\0' 放在字符串的末尾。让我们尝试输出上面的字符串:
实例
当上面的代码被编译和执行时,它会产生下列结果:
Greeting message: Hello
C++ 中有大量的函数用来操作以 null 结尾的字符串:supports a wide range of functions that manipulate null-terminated strings:
序号 | 函数 & 目的 |
---|---|
1 | strcpy(s1, s2); 复制字符串 s2 到字符串 s1。 |
2 | strcat(s1, s2); 连接字符串 s2 到字符串 s1 的末尾。 |
3 | strlen(s1); 返回字符串 s1 的长度。 |
4 | strcmp(s1, s2); 如果 s1 和 s2 是相同的,则返回 0;如果 s1<s2 则返回值小于 0;如果 s1>s2 则返回值大于 0。 |
5 | strchr(s1, ch); 返回一个指针,指向字符串 s1 中字符 ch 的第一次出现的位置。 |
6 | strstr(s1, s2); 返回一个指针,指向字符串 s1 中字符串 s2 的第一次出现的位置。 |
下面的实例使用了上述的一些函数:
实例
当上面的代码被编译和执行时,它会产生下列结果:
strcpy( str3, str1) : Hello strcat( str1, str2): HelloWorld strlen(str1) : 10
C++ 中的 String 类
C++ 标准库提供了 string 类类型,支持上述所有的操作,另外还增加了其他更多的功能。我们将学习 C++ 标准库中的这个类,现在让我们先来看看下面这个实例:
现在您可能还无法透彻地理解这个实例,因为到目前为止我们还没有讨论类和对象。所以现在您可以只是粗略地看下这个实例,等理解了面向对象的概念之后再回头来理解这个实例。
实例
当上面的代码被编译和执行时,它会产生下列结果:
str3 : Hello str1 + str2 : HelloWorld str3.size() : 10
小马
129***2060@qq.com
string类提供了一系列针对字符串的操作,比如:
下面是关于string类的实例:
小马
129***2060@qq.com
自娱、自乐
183***3822@qq.com
C++ 中输入的方式其实还有很多,下面来介绍一种与 C 语言中 getchar() 类似的。
cin.getline() 是在输入一段字符完成后开始读取数据(注意,是输入完成后,以Enter为结束标志)
下面是一实例:输入一串字符,编程统计其中的数字个数和英文字母个数。输入的字符以 # 为结束标志。
自娱、自乐
183***3822@qq.com
lhshengshi
510***747@qq.com
字符串与vector
字符串字面值与标准库string不是同一种类型
strlen、sizeof与size()求字符串长度的区别
标准string库中的getline函数返回时会丢弃换行符const iterator与const_iterator的区别
任何改变vector长度的操作都会使已存在的迭代器失效。如:在调用push_back之后,就不能再信赖指向vector的迭代器了
lhshengshi
510***747@qq.com
WOWTOT
573***580@qq.com
参考地址
之前一直搞不清 sizeof 和 strlen 到底该怎么区分,最近查了资料:
1、sizeof 操作符的结果类型是 size_t,它在头文件中 typedef 为 unsigned int 类型。该类型保证能容纳实现所建立的最大对象的字节大小。
2、sizeof 是运算符,strlen 是函数。
3、sizeof 可以用类型做参数,strlen 只能用 char* 做参数,且必须是以 \0 结尾的。
sizeof 还可以用函数做参数,比如:
输出的结果是 sizeof(short),即 2。
4、数组做 sizeof 的参数不退化,传递给 strlen 就退化为指针了。
5、大部分编译程序在编译的时候就把 sizeof 计算过了,是类型或是变量的长度,这就是 sizeof(x) 可以用来定义数组维数的原因。
6、strlen 的结果要在运行的时候才能计算出来,是用来计算字符串的长度,不是类型占内存的大小。
7、sizeof 后如果是类型必须加括弧,如果是变量名可以不加括弧。这是因为 sizeof 是个操作符不是个函数。
8、当适用一个结构类型或变量时, sizeof 返回实际的大小;当适用一静态地空间数组, sizeof 归还全部数组的尺寸;sizeof 操作符不能返回动态地被分派了的数组或外部的数组的尺寸。
数组作为参数传给函数时传的是指针而不是数组,传递的是数组的首地址, 如:
都等价于
在 C++ 里参数传递数组永远都是传递指向数组首元素的指针,编译器不知道数组的大小。
如果想在函数内知道数组的大小, 需要这样做:
进入函数后用memcpy拷贝出来,长度由另一个形参传进去
看了上面的详细解释,发现两者的使用还是有区别的,从这个例子可以看得很清楚:
上面是对静态数组处理的结果,如果是对指针,结果就不一样了。
WOWTOT
573***580@qq.com
参考地址
dx_djh
a14***40357@163.com
关于字符数组为什么可以以数组名来用cout输出数组内容,而普通数组不行。
先上范例:
输出结果为:
从以上范例可以看出,普通数组中以数组名用cout来输出,只会得到一串地址;用字符数组则会输出数组中的内容。
那为什么会这样呢?
答案:因为 char 型数组中的每一个元素都是一字节,所以每一个字符之间的地址都是 +1 的是连续的,所以当 cout 输出时读到字符数组中的 \0 便停止输出; 而 int 数组每个元素占 4 个字节所以数个数组中每个元素地址的间隔是 4,但其实它也是连续的,出现乱码是因没找到结束符。
dx_djh
a14***40357@163.com
戒空
116***0329@qq.com
Vs2017 使用 strcpy 的时候会报错,提示 strcpy 是不安全的,需要用 strcpy_s 代替。
戒空
116***0329@qq.com
maxven
max***@qq.com
<cstring> 创建详解
maxven
max***@qq.com
maxven
max***@qq.com
参考地址
<cstring> assign() 、 copy() 详解:
maxven
max***@qq.com
参考地址
maxven
max***@qq.com
<cstring> append() 详解及其扩展(int, char):
maxven
max***@qq.com
阳平
yua***ongtt@163.com
参考地址
C++ 中常见的几种输入字符串的方法如下:
cin、cin.get()、cin.getline()、getline()、gets()、getchar()
1. cin>>
用法一:最常用、最基本的用法,输入一个数字:
用法二:接受一个字符串,遇“空格”、“Tab”、“回车”都结束
2. cin.get()
用法一:cin.get(字符变量名)可以用来接收字符
用法二:cin.get(字符数组名,接收字符数)用来接收一行字符串,可以接收空格
用法三:cin.get(无参数)没有参数主要是用于舍弃输入流中的不需要的字符, 或者舍弃回车, 弥补cin.get(字符数组名,接收字符数目)的不足.
3.cin.getline()
cin.getline(): 接受一个字符串,可以接收空格并输出
接受5个字符到m中,其中最后一个为'\0',所以只看到4个字符输出;
如果把5改成20:
延伸:
cin.getline()实际上有三个参数,cin.getline(接受字符串到m,接受个数5,结束字符)
当第三个参数省略时,系统默认为'\0' 是‘/n’吧。
如果将例子中cin.getline()改为cin.getline(m,5,'a');当输入jlkjkljkl时输出jklj,输入jkaljkljkl时,输出jk
当用在多维数组中的时候,也可以用cin.getline(m[i],20)之类的用法:
测试:
4. getline()
getline() :接受一个字符串,可以接收空格并输出,需包含 #include<string>。
测试:
和cin.getline()类似,但是cin.getline()属于istream流,而getline()属于string流,是不一样的两个函数
5. gets()
gets(): 接受一个字符串,可以接收空格并输出,需包含 #include<string>。
测试:
类似cin.getline()里面的一个例子,gets()同样可以用在多维数组里面:
测试:
自我感觉gets()和cin.getline()的用法很类似,只不过cin.getline()多一个参数罢了;
这里顺带说明一下,对于本文中的这个kskr1,kskr2,kskr3的例子,对于cin>>也可以适用,原因是这里输入的没有空格,如果输入了空格,比如“ks kr jkl[回车]”那么cin就会已经接收到3个字符串,“ks,kr,jkl”;再如“kskr 1[回车]kskr 2[回车]”,那么则接收“kskr,1,kskr”;这不是我们所要的结果!而cin.getline()和gets()因为可以接收空格,所以不会产生这个错误;
6.getchar()
getchar() :接受一个字符,需包含 #include<string>。
测试:
getchar()是C语言的函数,C++也可以兼容,但是尽量不用或少用;
阳平
yua***ongtt@163.com
参考地址
周大侠
277***091@qq.com
@dx_djh
关于整形数组的解释是错误的,即使整形数组加上结束符,cout输出的也是地址,这是c++的机制。只有数组是char类型时,cout数组名才会输出内容,其他类型的都会输出地址。
周大侠
277***091@qq.com
秋叶
251***7981@qq.com
原始字符串(C++11)
R"(字符串)" 为默认格式的原始字符串,原始字符串内的字符不进行转义。 输出:
自定义分隔符
分隔符可支持自定义,写在括号外部,左右需要一致,不是所有的字符都可以设置为分隔符:
输出:
字符串前缀:
实例:
输出:
字符串前缀与原始字符串组合:
输出:
秋叶
251***7981@qq.com