1、第第7章章 字符串字符串 字符串操作函数 数字与字符串转换 阶段案例字符数组与字符串 字符串指针 字符串的输入输出7.1 字符数组和字符串字符数组是由字符类型的元素所组成的数组,字符串就存储在字符数组中,在访问字符数组时,可使用下标法读取指定位置的字符,也可使用%s格式将字符数组中的元素以字符串的形式全部输出。7.1.1 字符数组字符数组定义方式与整型数组类似:char 数组名数组大小;/一维字符数组例如,定义字符数组:char ch6;char c5=h,e,l,l,o;访问字符数组中的元素c0;/第1个元素c1;/第2个元素c2;/第3个元素脚下留心:字符数组初始化时注意事项脚下留心:字符
2、数组初始化时注意事项字符数组的初始化很简单,但是要注意以下几点:(1)初始项不能多于字符数组的大小,否则编绎器会报错。char str2=a,b,c;/错误写法(2)如果初始项值少于数组长度,则空余元素均会被赋值为空字符(0)。char str5=a,b,c;/后面剩余的两个元素均被赋值为0脚下留心:字符数组初始化时注意事项脚下留心:字符数组初始化时注意事项字符数组的初始化很简单,但是要注意以下几点:(3)如果没有指定数组大小,则编绎器会根据初始项的个数为数组分配长度。char str=a,b,c;/与char str3=a,b,c;相同(4)二维字符数组的初始化与整型二维数组类似。char
3、str22=a,b,c,d;7.1.2 字符串字符串是由数字、字母、下划线、空格等各种字符组成的一串字符,由一对英文半角状态下的双引号(“”)括起来。“abcde“/字符串“/字符串7.1.2 字符串字符串在末尾都默认有一个0作为结束符。注 意7.1.2 字符串在C语言中,字符串的存储和处理都是通过字符数组来实现的,存储字符串的字符数组必须以空字符0(空字符)结尾。当把一个字符串存入一个字符数组时,也把结束符0存入数组,因此该字符数组的长度是字符串实际字符数加1。7.1.2 字符串字符串由字符数组进行存储,那么可以直接使用一个字符串常量来为一个字符数组赋值。char char_array6=h
4、ello;char char_array=hello;上述两个字符数组的大小都是6,这是因为字符串末尾有一个0结束符。它们等同于下面数组的定义:char char_array6=h,e,l,l,o,0;7.1.2 字符串 小提示:0字符字符串其实就是一个以空字符0结尾的字符数组,在定义存储字符串的数组时,要手动在数组末尾加上0,或者直接使用字符串对数组进行初始化。7.1.2 字符串字符数组的输出:字符数组可以通过%s格式化输出,直接输出数组名。char char_array6=hello;printf(%s,char_array);/结果为hello7.1.2 字符串获取字符串的长度:C语言中
5、的strlen()函数获取字符串的长度:unsigned int strlen(char*s);示例代码如下:strlen(hello);/获取字符串hello的长度strlen(char_array);/获取字符数组char_array中存储的字符串的长度7.1.2 字符串使用strlen()函数得到的字符串的长度并不包括末尾的空字符0。注 意7.1.2 字符串 小提示:strlen()函数与sizeof运算符(1)sizeof是运算符;strlen()是C语言标准库函数,包含在string.h头文件中。(2)sizeof运算符功能是获得所建立的对象的字节大小,计算的是类型所占内存的多少;s
6、trlen()函数是获得字符串所占内存的有效字节数。7.1.2 字符串 小提示:strlen()函数与sizeof运算符(3)sizeof运算符的参数可以是数组、指针、类型、对象、函数等;strlen()函数的参数是字符串或以0结尾的字符数组。(4)sizeof运算符计算大小是在编绎时就完成,因此不能用来计算动态分配内存的大小;strlen()结果要在运行时才能计算出来。7.1.3 字符串与指针在C语言中,字符型指针用char*来定义,它不仅可以指向一个字符型常量,还可以指向一个字符串。字符串使用字符数组进行存储,因此,指针字符串的指针其实是指向了存储字符串的数组。字符串与指针7.1.3 字符
7、串与指针char arr6=nihao;/定义一个字符数组arr,存储字符串nihaochar*p=arr;/定义一个字符型指针p,指向数组arr字符指针p指向字符串arr,它们之间的逻辑关系如下图。7.1.3 字符串与指针通过字符指针引用字符数组中的元素:(1)下标法:p1;(2)指针运算:*(p+1);7.1.3 字符串与指针当字符指针指向字符串时,如果以%s格式化输出,则直接输出字符串;如果以%d等整型格式化输出,则输出的是字符串所在空间的首地址。printf(“%s”,char_array);/输出字符数组char_array中的字符串printf(“%d”,char_array);/
8、输出字符数组char_array的地址7.1.3 字符串与指针当定义指向字符串的指针时,除了使用数组为指针初始化,还可以使用字符串直接给指针进行初始化。char*p1=nihao;7.1.3 字符串与指针在用字符数组初始化字符指针之前,字符串已经存在于字符数组在栈区开辟的内存空间中,字符指针只需存储字符数组的地址即可;而用字符串常量初始化字符指针时,系统会先将字符串常量放入常量区,再用指针变量存储字符串的首地址。7.1.3 字符串与指针使用字符数组与字符串初始化字符指针的区别。7.1.3 字符串与指针字符指针与字符数组在初始化、赋值等方面的不同。(1)初始化:可以对字符指针进行赋值,但不能对数
9、组名进行赋值。(2)赋值方式:字符数组(或字符串)之间只能单个元素赋值或使用复制函数;字符指针则无此限制。(3)运算:字符指针可以通过指针运算改变其值,而数组名是一个指针常量,其值不可以改变。(4)字符串中字符的引用:数组可以用下标法和指针运算引用数组元素;字符串也可以用这两种方法来引用字符串的字符元素。7.2.1 常见的输入函数1、getc()函数getc()函数用来读取用户输入的单个字符,其函数声明如下:int getc(FILE*stream);getc()函数接收一个文件指针作为参数,它可以从该文件指针中读取一个字符,然后将字符强制转换为int类型返回,当读取到末尾或发生错误时返回EO
10、F(-1)。7.2.1 常见的输入函数2、getchar()函数getchar()函数用于从标准输入中读取一个字符,其函数声明如下:int getchar(void);getchar()没有参数,可直接使用,其返回值为读取到的字符。7.2.1 常见的输入函数3、gets()函数gets()函数用于读取一个字符串,其函数声明如下:char*gets(char*str);gets()函数读取换行符之前的所有字符(不包括换行符本身),并在字符串的末尾添加一个空字符0用来标记字符串的结束,读取到的字符串会以指针形式返回。7.2.1 常见的输入函数使用gets()函数时,用户定义的字符数组的长度必须大于
11、用户输入的字符串长度,否则程序会发生“缓冲区溢出”错误。注 意7.2.2 常见的输出函数1、putc()函数putc()函数用于将一个字符输出到指定流中,其函数声明如下:int putc(int char,FILE*fp);putc()函数接收两个参数:字符和文件指针,其返回值是一个整型数据,它将输出的字符以整型数据的形式返回。7.2.2 常见的输出函数2、putchar()函数putchar()函数用于将一个字符输出到标准输出,其函数声明如下:int putchar(int char);putchar()函数接收一个字符参数,它将这个字符输出到标准输出,然后返回该字符。7.2.2 常见的输出
12、函数3、puts函数puts()函数用来输出一整行字符串,其函数声明如下:int puts(const char*str);puts()接收的参数是一个字符串指针,该指针指向要输出的字符串,并且会自动在字符串末尾追加换行符n。如果调用成功,则返回一个int类型的正数,否则返回EOF。7.2.2 常见的输出函数 小提示:printf()与puts()的区别与puts()函数相比,printf()函数不会一次输出一整行字符串,而是根据格式化字符串输出一个个“单词”。由于进行了额外的数据格式化工作,在性能上,printf()比puts()慢。但另一方面,printf()还可以直接输出各种不同类型的数
13、据,因此它比puts()使用的更广泛。7.3.1 字符串比较函数1、strcmp()函数strcmp()函数用于比较两个字符串的内容是否相等:int strcmp(const char*str1,const char*str2);参数str1和str2代表要进行比较的两个字符串。如果两个字符串的内容相同,strcmp()返回0,否则返回非零值。7.3.1 字符串比较函数函数strcmp()只能接收字符指针作为参数,不接收单个字符;如果传入的是某个字符(如a),那么a会被视为指针,程序将会报错。注 意7.3.1 字符串比较函数2、strncmp()函数strncmp()函数用来比较两个字符串中前
14、n个字符是否完全一致。:int strncmp(const char*str1,const char*str2,size_t n);参数n表示要比较的字符个数。当然,如果字符串str1和str2的长度都小于n,那么就相当于使用strcmp()函数对字符串进行比较。7.3.2 字符串查找函数1、strchr()函数strchr()函数用来查找指定字符在指定字符串中第1次出现的位置。char*strchr(const char*str,char c);参数str为被查找的字符串,c是指定的字符。如果字符串str中包含字符c,strchr()函数将返回一个字符指针,该指针指向字符c第1次出现的位置,
15、否则返回空指针。7.3.2 字符串查找函数2、strrstr()函数strrchr()函数用来查找指定字符在指定的字符串中最后1次出现的位置。char*strrchr(const char*str,char c);参数str为被查找的字符串,c是指定的字符。如果字符串str中包含字符c,strchr()函数将返回一个字符指针,该指针指向字符c最后一次出现的位置,否则返回空指针。7.3.2 字符串查找函数3、strstr()函数strstr()判断在字符串中是否包含指定子串。char*strstr(const char*haystack,const char*needle);参数haystack
16、是被查找的字符串,needle是子字符串。如果在字符串haystack中找到了字符串needle,则返回子字符串的指针,否则返回空指针。7.3.3 字符串连接函数1、strcat()函数strcat()函数用来实现字符串的连接。char*strcat(char*dest,const char*src);参数dest为目标字符串,参数src接收源字符串,strcat()将参数src指向的字符串复制到参数dest所指字符串的尾部,覆盖dest所指字符串的结束字符,实现拼接。7.3.3 字符串连接函数当调strcat()函数时,第1个参数必须有足够空间在存储连接进来的字符串,否则会产生缓冲区溢出问题
17、。注 意7.3.3 字符串连接函数2、strncat()函数strncat()函数用于连接指定长度的字符串。char*strncat(char*dest,const char*src,size_t n);该函数用于设置从src所指字符数组中取出的字符个数。7.3.4 字符串复制函数strcpy()函数strcpy()函数用于实现字符串复制功能。char*strcpy(char*dest,const char*src);strcpy()函数接受两个参数,其功能是把从src地址开始且含有0结束符的字符串复制到以dest开始的地址空间,返回指向dest的指针。7.3.4 字符串复制函数src和des
18、t所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。注 意7.3.4 字符串复制函数strcpy()函数用法:char arr15=hello,China;char*p=ABCD;strcpy(arr,p);这段代码的复制过程如右图。7.4 数字与字符串的转换1、atoi()函数atoi()函数用于将一个数字字符串转换为对应的十进制数。int atoi(const char*str);参数str用于接收记录数字的字符串,若函数调用成功,将返回转换后的十进制整数;否则返回0。需要注意的是,atoi()的声明位于stdlib.h文件中,因此需要使用include指令引用头文件s
19、tdlib.h。7.4 数字与字符串的转换2、atof()函数atof()函数用于将一个数字字符串转换为浮点数。double atof(const char*str);参数str用于接受记录数字的字符串,若函数调用成功,将返回转换后的浮点数,否则返回0。atof()函数声明位于stdlib.h文件中,如果使用该函数,则需要包含头文件。7.4 数字与字符串的转换3、sprintf()函数sprintf()函数是字符串格式化函数,主要功能是把格式化的数据写入某个字符串中。int sprintf(char*buffer,const char*format,argument );参数buffer指向将
20、要写入的字符串的缓冲区,参数format表示格式化字符串,参数aegument为可选参数,表示的是需要转换的数据。多学一招:使用函数多学一招:使用函数itoaitoa()()将整数转换为字符串将整数转换为字符串itoa()函数用于将一个整数转换为不同进制下的字符串。char*itoa(int val,char*dst,int radix);第1个参数val表示的是待转换的数,第2个参数表示的是目标字符数组,第3个参数表示的是要转换的进制。多学一招:使用函数多学一招:使用函数itoaitoa()()将整数转换为字符串将整数转换为字符串itoa()不是C语言标准中规定的函数,因此在某些平台(如Li
21、nux)上是无法使用的,这种情况下可使用sprintf()。注 意7.5 阶段案例回文字符串一、案例描述回文字符串就是正读反读都一样的字符串,比如,“level”和“noon”都是回文字符串。案例要求从键盘中输入字符串,并判断此字符串是否为回文字符串。7.5 阶段案例回文字符串二、案例分析判断一个字符串是否是回文字符串,则可以使用上一章学习的指针,使用两个指针分别指向字符串的开头与末尾,判断两个指针所指向的字符是否相同,如果不同则不是回文字符串;如果相同则分别向中间移动,再次比较是否相同,这样直到所有字符比较完毕。7.5 阶段案例回文字符串三、案例实现思路(1)定义一个数组存储从键盘输入的字符
22、串,并且定义一个变量length记录数组中字符串的长度。(2)分别定义两个指针指向字符串开头与末尾。7.5 阶段案例回文字符串三、案例实现思路(3)比较两个指针指向的字符是否相同,如果不同提示不是回文字符串,如果相同,则把指向字符串开头的指针加1,向后移动指针并指向后一个字符,同时把指向字符串末尾的指针减1,向前移动指针并指向前一个字符,然后继续判断此时指针指向的两个字符是否相同,直到检查完字符串中所有字符为止。(4)最后根据返回值判断字符串是否为回文字符串。7.6 本章小结本章首先讲解了C语言中字符数组、字符串的概念与定义,以及字符串与指针的关系,然后讲解了字符串的输入输出,之后讲解了字符串常用的操作函数,最后讲解了数字与字符串之间的转换。字符串在实际开发中应用广泛,通过本章的学习,希望大家能够熟练掌握字符串的操作。