汉扬编程 C语言入门 C\\C++语言22|C风格字符串及其字符串函数、字符串类

C\\C++语言22|C风格字符串及其字符串函数、字符串类

字符串处理是任何编程语言都要涉及到的内容。

C\\C++语言22|C风格字符串及其字符串函数、字符串类

在C中,字符串是以空字符\’\\0\’为终止元素的字符数组来表示的,称为C风格的字符串,C标准库同时在库<string.h>中提供了一族字符串操作函数。

在C++中,字符串被封装为类,由类库<string>提供相应成员函数的接口和实现。

相对来说,C风格字符串效率较高,string类安全性要好。同时,因为C++出现的时间相对于C较晚,一些函数库是在C++出现之前开发的,所以使用的是C风格的字符串,而不是string类,如win32 API。

1 C风格字符串及其库函数在C中,字符串是以空字符(\\0)结尾的字符数组。

可以像其他数组那样声明并初始化字符串:

char carr[] = {\’w\’,\’w\’,\’u\’,\’h\’,\’n\’,\’\\0\’};也可以用字面量初始化字符串的简捷方式:

char carr[] = \”wwuhn\”;这种初始化方法不需要使用空字符,而是由编译器自动添加。

当然也可以使用指针的方式:

char *cp = \”wwuhn\”;字符串的字面量会保存到内存的数据段(字符串以外的字面量会以代码的形式存在),返回的是一个常量指针。数组初始化不一样,其右值的字符串保存在栈中。

所以,cp指向的是字面量,相当于常量,不能单个元素更改(其本身cp是一个变量,可以另有指向)。

cp[2] = \’r\’; //错误cp = carr; //正确因为其是常量指针,所以一般写成:

const char *cp = \”wwuhn\”;carr是常量,数组名是指针常量,本身不能再另有指向,而其指向的内容却是可以更新的:

carr[2] = \’r\’; //正确carr = cp; //错误C或C++的函数库中提供了一些用来处理字符串的函数。这些函数在库<string.h>(C++中写成<cstring>中。

空字符\’\\0\’标记字符数组中存储的C 字符串的结束。如果字符数组以这种方式使用,该数组就称为C 字符串变量。虽然空字符\’\\0\’要写成两个符号,但实际只代表一个字符,可以用char 类型的变量或者字符数组的索引变量来存储它。

不能用=对C 字符串变量进行赋值。用==测试C 字符串相等性也得不到你希望的结果。原因很简单,因为C 字符串和C 字符串变量本质上是数组。

为C 字符串变量赋值不像为其他类型的变量赋值那么简单。

char aString[10];aString = \”Hello\”; //非法,只能在初始化时赋值虽然可在声明时用等号为C 字符串变量赋值,但在程序的其他任何地方都不能这样做。从技术上说,在声明时使用等号,就像下面这样:

char happyString[7] = \”DoBeDo\”;它其实是一个初始化操作,而不是赋值操作。要为C 字符串变量赋值,必须采取其他方式。

可采取许多不同的方式为C 字符串变量赋值。最简单的是使用预定义函数strcpy,

strcpy(aString, \”Hello\”);

这也是为什么将后面的值复制到前面的值,而不是返回一个新的存储空间的指针的原因。

这会将aString 的值设为\”Hello\”。遗憾的是,strcpy 函数的这个版本不检查复制的字符串是否超过字符串变量(第一个参数)的长度。

许多(但并非全部)C++版本还提供了strcpy 的一个更安全的版本。这个安全版本要拼写成strncpy(多了一个n)。strncpy 函数要获取第3 个参数,指定最多能复制多少字符。

char anotherString[10];strncpy(anotherString, aStringVariable, 9);使用这个strncpy 函数,最多能从C 字符串变量aStringVariable 中复制9 个字符(包括\’\\0\’),无论aStringVariable 中的字符串有多长。

也不能在表达式中使用操作符==测试两个C 字符串是否相等。更糟的是,可以为C 字符串使用==,但作用不是测试C 字符串是否相等。所以,用==测试两个C 字符串的相等性可能得到错误结果,而且编译器不报告任何错误!要测试两个C 字符串是否相等,可以使用预定义函数strcmp。例如下面的代码:

if (strcmp(cString1, cString2))cout << \”The strings are NOT the same.\”;elsecout << \”The strings are the same.\”;注意,strcmp 函数的工作方式可能和你想的不同。两个字符串不匹配,结果反而是true。strcmp 函数每次比较C 字符串参数的一个字符。任何时候只要cString1 的一个字符的数值编码小于cString2 的对应字符的数值编码,测试就会停止,并返回一个负数。

如果cString1 的字符大于cString2 的对应字符,则返回一个正数(strcmp 的有些实现返回字符编码的差值,但不应依赖于此)。

两个C 字符串完全相同,则返回0。字符比较依据的是词典顺序(lexicographic order)。它的重点是,两个字符串采用全部大写或小写的形式,词典顺序就和字母顺序一样。

基于词典顺序,在C 字符串比较结果是小于、大于或者等于的情况下,strcmp 分别返回负值、正值或零。在if 或循环语句中将strcmp 作为布尔表达式使用,在字符串不相等的前提下,返回的所有非零值都被转换成true;在字符串相等的前提下,返回的零值被转换成false。所以在测试C 字符串的相等性时,务必记住这一反转逻辑。

字符串库函数(包括内存块函数):

strcat() 连接两个字符串strchr() 查找某字符在字符串中首次出现的位置strcmp() 比较两个字符串strcoll() 采用目前区域的字符排列次序来比较字符串strcpy() 拷贝字符串strcspn() 在某字符串中匹配指定字符串strerror() 返回错误码对应的文本信息strlen() 返回指定字符串的长度strncat() 连接某一长度的两个字符串strncmp() 比较某一长度的两个字符串strncpy() 复制某一长度的一个字符串到另一字符串中strpbrk() 查找某字符串在另一字符串中首次出现的位置strrchr() 查找某字符在字符串中末次出现的位置strspn() 返回子串的长度,子串的字符都出现包含于另一字符串中strstr() 在一字符串中查找指定的子串首次出现的位置strtod() 将字符串转换成浮点数strtok() 查找指定字符之前的子串strtol() 将字符串转换成长整型数strtoul() 将字符串转换成无符号长整型数strxfrm() 转换子串, 可以用于字符串比较 memchr() 在某一内存范围中查找一特定字符memcmp() 比较内存内容memcpy() 拷贝内存内容memmove() 拷贝内存内容memset() 将一段内存空间填入某值2 字符串格式化在将各种类型的数据构造成字符串时,sprintf 的强大功能很少会让你失望。由于sprintf 跟printf 在用法上几乎一样,只是打印的目的地不同而已,前者打印到字符串中,后者则直接在命令行上输出。这也导致sprintf 比printf 有用得多。

sprintf指的是字符串格式化命令,主要功能是把格式化的数据写入某个字符串中。sprintf 是个 变参 函数。使用sprintf 对于写入buffer的字符数是没有限制的,这就存在了buffer溢出的可能性。解决这个问题,可以考虑使用 snprintf 函数,该函数可对写入字符数做出限制。

实例:

#include <stdio.h>#include <stdlib.h>int main() { char buffer[200], s[] = \”computer\”, c = \’l\’; int i = 35, j; float fp = 1.7320534f; // 格式化并打印各种数据到buffer j = sprintf( buffer, \” String: %s\\n\”, s ); j += sprintf( buffer + j, \” Character: %c\\n\”, c ); j += sprintf( buffer + j, \” Integer: %d\\n\”, i ); j += sprintf( buffer + j, \” Real: %f\\n\”, fp ); printf( \”Output:\\n%s\\ncharacter count = %d\\n\”, buffer, j ); system(\”pause\”); return 0;}输出:

3 C++string类string 类在名称同为的库中定义,定义放在std 命名空间中。所以,要使用string 类,代码必须包含以下语句(或其他等价的语句):

#include <string>using namespace std;string 类的默认构造函数将string 对象初始化成空字符串,另一个构造函数获取一个C 字符串作为参数,将string 对象初始化成一个值来表示由参数给定的字符串。例如:

string s1, s2(\”Hello\”);string对象要获得C风格表示,可使用成员函数c_str()。

string类函数成员:

append() 在字符串的末尾添加文本assign() 为字符串赋新值at() 按给定索引值返回字符begin() 返回一个迭代器,指向第一个字符c_str() 将字符串以C字符数组的形式返回capacity() 返回重新分配空间前的字符容量compare() 比较两个字符串copy() 将内容复制为一个字符数组data() 返回内容的字符数组形式empty() 如果字符串为空,返回真end() 返回一个迭代器,指向字符串的末尾。(最后一个字符的下一个位置)erase() 删除字符find() 在字符串中查找字符find_first_of() 查找第一个与value中的某值相等的字符find_first_not_of() 查找第一个与value中的所有值都不相等的字符find_last_of() 查找最后一个与value中的某值相等的字符find_last_not_of() 查找最后一个与value中的所有值都不相等的字符get_allocator() 返回配置器insert() 插入字符length() 返回字符串的长度max_size() 返回字符的最大可能个数rbegin() 返回一个逆向迭代器,指向最后一个字符rend() 返回一个逆向迭代器,指向第一个元素的前一个位置replace() 替换字符reserve() 保留一定容量以容纳字符串(设置capacity值)resize() 重新设置字符串的大小rfind() 查找最后一个与value相等的字符(逆向查找)size() 返回字符串中字符的数量substr() 返回某个子字符串swap() 交换两个字符串的内容4 宽字符串对于字符类型char,其宽度为1个字节,用多个字节来代表的字符称之为宽字符。

<wchar.h>中定义了类型wchar_t(unsigned short),用来表示WCHAR,及宽字符。

宽字符字符串表示为一个 wchar_t[] 数组并由 wchar_t* 指针指向它。可以通过用字母 L 作为字符的前缀将任何 ASCII 字符表示为宽字符形式。例如,L\’\\0\’ 是终止宽(16 位)NULL 字符。同样,可以通过用字母 L 作为 ASCII 字符串的前缀 (L\”Hello\”) 将任何 ASCII 字符串表示为宽字符字符串形式。

通常,宽字符在内存中占用的空间比多字节字符多,但处理速度更快,因为很多系统的内核包括Windows NT内核都是从底层向上使用Unicode编码的。另外,在多字节编码中一次只能表示一个区域设置,Unicode编码可以毫无障碍地在世界上任何书面语言的字符中转换。

实例1

#include <iostream>using namespace std;#include <wchar.h>void main(){ wchar_t wstr[] = L\”hi\”; wcout<<wstr<<endl;}实例2

#include <tchar.h>#include <stdio.h>void main(){ TCHAR wstr[] = \”你好\”; printf(\”%s\\n\”,wstr);}实例3

#include <iostream>#include <windows.h>using namespace std;int main(){ char input[50]; cout<<\”请输入包含汉字的字符串:\”; cin>>input; int size; size=::MultiByteToWideChar(CP_ACP,0,input,strlen(input)+1,NULL,0); if(size==0) return -1; wchar_t *widebuff=new wchar_t[size]; ::MultiByteToWideChar(CP_ACP,0,input,strlen(input)+1,widebuff,size); cout<<endl<<\”输出:\”<<input<<endl; system(\”pause\”);}/*请输入包含汉字的字符串:中国abc输出:中国abc/*当然,也可以用字符串类string来处理:

std::string是ANSI,但std::wstring是Unicode。如果要定义Unicode,只需要在正常的ANSI字符串前加上“L”就可以了。

#include <iostream>#include <string>using namespace std;void main(){ string str = \”你好\”; wstring str2 = L\”你好\”; cout<<str.length()<<endl;//4 cout<<str2.length()<<endl;//2,string处理wstring有问题 wcout.imbue(locale(\”chs\”)); wcout<<str2<<endl;//你好}-End-

本文来自网络,不代表汉扬编程立场,转载请注明出处:http://www.hyzlch.com/cjia/7039.html

是什么意思c语言中 bool flag[10]={0}?

c语言编程里面格式控制串是什么?能举例说明吗?有什么用

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

返回顶部