阅读 ‧ 电子书库 说  明
strcmp()函数用于比较字符串,而不是字符。因此可以使用诸如“apples”和“A”之类的参数;但是不能使用字符参数,如'A'。考虑到char类型是整数类型,因此可以使用关系运算符来对字符进行比较。假定word是一个存储在char数组里的字符串,ch是一个char变量。那么下面的语句是合法的:
阅读 ‧ 电子书库
但是,不能使用ch或‘q’作为strcmp()的参数。

程序清单11.19使用strcmp()函数来判断一个程序是否应该停止读取输入。

程序清单11.19 quit_chk.c程序

阅读 ‧ 电子书库

当程序遇到一个EOF字符(此时gets()返回空)时,或者您输入单词quit时,或者达到LIM的限制时,程序就退出对输入的读取。

广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元

顺便提一下,有时候输入一个空行来终止输入更方便,也就是说,在一个新行中不输入任何字符就按下Enter键或Return键。要这样做,您可以对while循环的控制语句做如下的修改:

阅读 ‧ 电子书库

此处,input[ct]是刚输入的字符串,input[ct][0]是该字符串的第一个字符。如果用户输入一个空行,gets()就把空字符放在第一个元素处,因此如下表达式是用来检测空输入行的:

阅读 ‧ 电子书库

11.5.5 strncmp()变种

strcmp()函数比较字符串时,一直比较到找到不同的相应字符,搜索可能要进行到字符串结尾处。而strncmp()函数比较字符串时,可以比较到字符串不同处,也可以比较完由第三个参数指定的字符数。例如,如果想搜索以“astro”开头的字符串,您可以限定搜索前5个字符。程序清单11.20示例了这个函数的使用。

程序清单11.20 starsrch.c程序

阅读 ‧ 电子书库

输出如下:

阅读 ‧ 电子书库

11.5.6 strcpy()和strncpy()函数

我们已经提到过,如果ptsl和pts2都是指向字符串的指针,则下面的表达式只复制字符串的地址而不是字符串本身:

阅读 ‧ 电子书库

假定您确实希望复制字符串,那么可以使用strcpy()函数。程序清单11. 21要求用户输入以q开头的单词。程序把输入复制到一个临时的数组里,如果第一个字母是q,程序就使用strcpy()函数把字符串从临时数组里复制到永久的目的地。strcpy()函数在字符串运算中的作用等价于赋值运算符。

程序清单11.21 copy1.c程序

阅读 ‧ 电子书库

阅读 ‧ 电子书库

下面是一个运行示例:

阅读 ‧ 电子书库

请注意只有当输入的单词通过了q判断,计数值i才会增加。还要注意程序使用了一个基于字符的判断:

阅读 ‧ 电子书库

这相当于,temp数组的第一个字符是否不为q?还可以使用一个基于字符串的判断:

阅读 ‧ 电子书库

这相当于,字符串temp和字符串“q”的第一个元素是否不同?

注意,第二个参数temp指向的字符串被复制到第一个参数qword[i]指向的数组中。复制的那份字符串被称为目标(target)字符串,最初的字符串被称为源(source)字符串。如果注意到它和赋值语句的顺序一样,目标字符串在左边,就容易记住参数的顺序。

阅读 ‧ 电子书库

确保目标数组对复制源字符串来说有足够大的空间就是您的责任了。看看下面语句有什么问题:

阅读 ‧ 电子书库

函数将把字符串“The C of Tranquility”复制到str指定的地址中,但是str没有初始化,因此这个字符串可能被复制到任何地方!

总之,strcpy()接受两个字符串指针参数。指向最初字符串的第二个指针可以是一个已声明的指针、数组名或字符串常量。指向复制字符串的第一个指针应指向空间大到足够容纳该字符串的数据对象,比如一个数组。记住,声明一个数组将为数据分配存储空间;而声明一个指针只为一个地址分配存储空间。

一、strcpy()的高级属性

strcpy()函数还有另外两个有用的属性。首先,它是char*类型,它返回的是第一个参数的值,即一个字符的地址;其次,第一个参数不需要指向数组的开始,这样就可以只复制数组的一部分。程序清单11. 22举例说明了这两个属性的使用。

程序清单11.22 copy2.c程序

阅读 ‧ 电子书库

输出如下:

阅读 ‧ 电子书库

注意,strcpy()从源字符串复制空字符。在这个例子中,空字符覆盖了that中的第一个t,这样新的字符串就以beast结尾(请参见图11.5) 。还要注意,ps指向copy的第8个元素(索引为7) ,这是因为第一个参数是copy+7。因此,puts(ps)从这个地方开始输出字符串。

阅读 ‧ 电子书库

图11.5 strcpy()使用指针

二、较为谨慎的选择:strncpy()

strcpy()和gets()函数同样都有一个问题,那就是都不检查目标字符串是否容纳得下源字符串。复制字符串使用strncpy()比较安全。它需要第三个参数来指明最大可复制的字符数。程序清单11. 23用strncpy()代替了程序清单11. 21中的strcpy() 。为了说明源字符串太大会产生的问题,它使用了一个相当小的目标字符串(7个元素,6个字符)。

程序清单11.23 copy3.c程序

阅读 ‧ 电子书库

下面是一个运行示例:

阅读 ‧ 电子书库

函数调用strncpy(target, source, n)从source把n个字符(或空字符之前的字符,由二者中最先满足的那个决定何时终止)复制到target。因此,如果源字符串的字符数比n小,整个字符串都被复制过来,包括空字符。函数复制的字符数绝不会超过n,因此如果源字符串还没结束就达到了限制,就不会添加空字符。结果,最终的字符串可能有也可能没有空字符。出于这个原因,程序设置的n比目标数组的大小要少1,这样就可以把空字符放到数组的最后一个元素里。

阅读 ‧ 电子书库

这就确保您已经存储了一个字符串。如果源字符串确实可以容纳得下,和它一起复制的空字符就标志着字符串的真正结束。如果源字符串在目标数组中容纳不下,这个最后的空字符就标志着字符串的结束。

11.5.7 sprintf()函数

sprintf()函数是在stdio. h而不是在string. h里声明的。它的作用和printf()一样,但是它写到字符串里而不是写到输出显示。因此,它提供了把几个元素组合成一个字符串的一种途径。sprintf()的第一个参数是目标字符串的地址,其余的参数和printf()一样:一个转换说明字符串,接着是要写的项目的列表。

程序清单11. 24使用sprintf()把三个项目(两个字符串和一个数字)组合成一个单一的字符串。注意,使用sprintf()和使用printf()的方法一样,只是结果字符串被存放在数组formal中,而不是被显示在屏幕上。

程序清单11.24 format.c程序

阅读 ‧ 电子书库

下面是一个运行示例:

阅读 ‧ 电子书库

sprintf()命令获取输入,并把输入格式化为标准形式后存放在字符串formal中。

11.5.8 其他字符串函数

ANSIC库有20多个处理字符串的函数,下面的列表总结了其中最常用的一些:

阅读 ‧ 电子书库

该函数把s2指向的字符串(包括空字符)复制到sl指向的位置,返回值是sl。

阅读 ‧ 电子书库

该函数把s2指向的字符串复制到sl指向的位置,复制的字符数不超过n个。返回值是sl。空字符后的字符不被复制。如果源字符串的字符数少于n个,在目标字符串中就以空字符填充。如果源字符串的字符数大于或等于n个,空字符就不被复制。返回值是sl。

阅读 ‧ 电子书库

s2指向的字符串被复制到sl指向字符串的结尾。复制过来的s2所指字符串的第一个字符覆盖了sl所指字符串结尾的空字符。返回值是sl。

阅读 ‧ 电子书库

s2字符串中只有前n个字符被追加到sl字符串,复制过来的s2字符串的第一个字符覆盖了sl字符串结尾的空字符。s2字符串中的空字符及其后的任何字符都不会被复制,并且追加一个空字符到所得结果后面。返回值是sl。

阅读 ‧ 电子书库

如果sl字符串在机器编码顺序中落后于s2字符串,函数的返回值是一个正数;如果两个字符串相同,返回值是0;如果第一个字符串在机器编码顺序中先于第二个字符串,返回值是一个负数。

阅读 ‧ 电子书库

该函数的作用和strcmp()一样,只是比较n个字符后或者遇见第一个空字符时会停止比较,由二者中最先被满足的那一个条件终止比较过程。

阅读 ‧ 电子书库

该函数返回一个指向字符串s中存放字符c的第一个位置的指针(标志结束的空字符是字符串的一部分,因此也可以搜索到它)。如果没找到该字符,函数就返回空指针。

阅读 ‧ 电子书库

该函数返回一个指针,指向字符串sl中存放s2字符串中的任何字符的第一个位置。如果没找到任何字符,函数就返回空指针。

阅读 ‧ 电子书库

该函数返回一个指针,指向字符串s中字符c最后一次出现的地方(标志结束的空字符是字符串的一部分,因此也可以搜索到它)。如果没找到该字符,函数就返回空指针。

阅读 ‧ 电子书库

该函数返回一个指针,指向sl字符串中第一次出现s2字符串的地方。如果在sl中没找到s2字符串,函数就返回空指针。

阅读 ‧ 电子书库

该函数返回s字符串中的字符个数,其中不包括标志结束的空字符。

注意,这些原型使用关键字const来指出哪个字符串是函数不能改动的。例如,考虑下面这个原型:

阅读 ‧ 电子书库

这意味着s2指向一个不可改变的字符串,至少strcpy()函数不会改变它,但是sl指向的字符串却可以改变。这是因为,sl是需要改变的目标字符串,而s2是不应当有改变的源字符串。

第5章“运算符、表达式和语句”中已经讨论过,size_t类型是sizeof运算符返回的任何类型。C规定sizeof运算符返回一个整数类型,但是没有指定是哪种整数类型。因此size_t在一个系统上可以是unsigned int类型;在另一个系统上,又可以是unsigned long类型。string. h文件为您的特定系统定义了size_t,或者您可以参考其他有该定义的头文件。

前面已经提到过,参考资料5中列出了string. h系列中所有的函数。除了ANSI标准要求的那些,很多C实现还提供了其他一些函数。应该查看您的C实现的文档以了解可以使用哪些函数。

让我们看一下这些函数其中一个的简单使用。前面您已学习了fgets()函数。在读取一行输入时,这个函数把换行符存储到目标字符串中。可以使用strchr()函数来用一个空字符代替这个换行符。首先,使用strchr()找到换行符(如果有的话)。如果找到了,函数就返回这个换行符的地址,于是就可以在该地址放一个空字符:

阅读 ‧ 电子书库

如果strchr()没有找到换行符,说明fgets()在行未结束时就达到了大小限制。您可以给if加个else来处理这种情况。

接下来,我们看一个处理字符串的完整程序。