字符串
什么是字符串?
字符串常量是放在一堆双引号中的一串字符或符号。
任何一对双引号之间的任何内容都会被编译器视为字符串,包括特殊字符和嵌入的空格。
字符串的结尾时空字符,写作\0.
注意:C中的字符串总是由\0结束,所以字符串的长度永远比字符串中的字符数多1
其他位置的\0不能作为字符串的一部分,第一个\0的位置就是字符串的结尾部分
测试代码
#include <stdio.h> int main(void) { printf("The character \0 is used to terminate a string."); return 0; }
处理字符串和文本的办法
C语言对变量存储字符串的语法没有特殊的规定,而且C根本就没有字符串变量,也没有处理字符串的特殊运算符。
使用char类型的数组保存字符串,这是字符串变量的最简单的形式。
char saying[20];
这个saying变量可以存储一个至多包含19个字符的字符串,因为必须有一个位置给空字符。
也可以这样声明并初始化: char saying=“This is a string." 在这个例子中char数组的长度是18
也可以用一个字符串初始化char类型数组的部分元素,例如:
char str[40]="To be"; 这里str[0]~[4]是指定字符串元素,str[5]是空字符,后面为空。
处理标准信息是使用char数组并const声明为常量。如果声明了char为常量了,后面就不能更改这个数组了。
输出字符串:
#include <stdio.h> int main(void) { const char message[]="The end of the world is nigh"; printf("\nThe message is: %s",message); return 0; }
转换指定符为%s
直接使用数组存储字符串缺点是浪费内存,因为没有指定数组长度,所以数组的默认长度是最大的字符串的长度。所以确定字符串的长度是很重要的。
确定字符串长度demo:
#include <stdio.h> int main(void) { char str1[]="To be or not to be"; char str2[]=",that is the question"; int count1=0, count2=0; while(str1[count1]!='\0') { count1++; } printf("\nThe length of the string \"%s\" is %d characters.",str1,count1); while(str2[count2]!='\0') { count2++; } printf("\nThe length of the string \"%s\" is %d characters.",str2,count2); return 0; }
字符串操作
连接字符串(确定第一个字符串是否内存足够存储两个字符串的量,然后将字符串2复制到1的尾部)
#include <stdio.h> int main(void) { char str1[]="To be or not to be"; char str2[]=",that is the question"; int count1=0; int count2=0; while(str1[count1]) { count1++; } while(str2[count2]) { count2++; } int x=sizeof str1; if(x < count1+count2+1 ) /* a char size is 1 */ { printf("\nYou can't put a quart into a pint pot."); }else { count2=0; /* while(str2[count2]) { str1[count1++]=str2[count2++]; } */ while(str1[count++]=str2[count++]); str1[count1]='\0'; printf("\n%s\n",str1); } return 0; }
字符串数组
可以使用char类型的二位数组存储字符串,数组的每一行都用来存储一个字符串,这样就可以存入一串字符串。
demo:
char saying[3][32]={ "Manners maketh man." "Many hands make light work." "Too many cooks spoil the broth." };
不需要用括号括起每个字符串;必须指定最后一维的大小。
saying[i][j]第一个索引i指定数组中的行,第二个索引j指定该行中的一个字符。引用一个索引号,在方括号中只包括一个索引符。
demo:
#include <stdio.h> int main(void) { char saying[][32] ={ "Manners maketh man.", "Many hands make light work.", "Too many cooks spoil the broth." }; int length=sizeof saying/sizeof saying[1]; for(int i=0;i<length;i++) { printf("\n%s",saying[i]); } return 0; }
字符串函数
需要导入头文件<string.h>
复制字符串函数strcpy(string1,string2);(字符串替换函数)
参数是char数组名,将string2复制到string1中,取代原来的strig1的内容,也就是一个替换行数这个复制包括终止符号'\0'。
要求,string1的长度>=string2的长度。strcpy()函数不检查字符串长度,通常需要我们先进行判断。
确定字符串长度函数strlen().
strlen(字符串数组名);返回的是一个size_t类型的整数
size_t在头文件<stddef.h>定义
连接字符串函数stract()
strcat(str1,str2);将str2连接到str1的末尾,返回连接后的值
strncat(str1,str2,len);将str2的len个字符连接到str1的末尾,返回连接后的值
这两个函数也需要检查str1的内存是否足够进行操作在使用函数之前,否则,这个函数也会与其他字符串赋值函数一样会覆盖目标数组之后的内存空间。
demo:
#include <stdio.h> #include <stddef.h> #include <string.h> #define STR_LENGTH 40 int main(void) { char str1[STR_LENGTH]="To be or not to be"; char str2[STR_LENGTH]=",that is the question"; if(STR_LENGTH>strlen(str1)+strlen(str2)) { printf("\n%s\n",strcat(str1,str2)); } else { printf("\nYou can't pu a quare into a pot."); } if(STR_LENGTH>strlen(str1)+strlen(str2)) { printf("\n%s\n",strncat(str1,str2,5)); }else { printf("\nYou can't pu a quare into a pot."); } return 0; }
比较字符串函数strcmp()
strcmp(str1,str2)比较str1和str2两个字符串,返回int类型,对应str1大于、等于、小于str2
char str1[]="The quick brown fox"; char str2[]="The quick blank fox"; if(strcmp(str1,str2)<0) { printf("str1 is less than str2"); }
strncmp(str1,str2,len)比较str1和str2的前n个字符,返回int
char str1[]="The quick brown fox"; char str2[]="The quick black fox"; if(strncmp(str1,str2,10)<0) { printf("\n%s\n%s",str1,str2); }else { printf("\n%s\n%s",str2,str1); }
demo:
#include <stdio.h> #include <string.h> int main(void) { char word1[20]; char word2[20]; printf("\nType in the first word (less than characters):\n1:"); scanf("%s",&word1); printf("\nType in the second word (less than 20 characters):\n:"); scanf("%s",&word2); if(strcmp(word1,word2)==0) { printf("You have entered identical words"); }else { printf("%s preceds %s", (strcmp(word1,word2)<0)?word1:word2, (strcmp(word1,word2)<0)?word2:word1 ); } return 0; }
搜索字符串
指针的概念
指针式含有地址的变量,它含有内存中另一个包含数值位置的引用。
demo:
int Number=25; int *pNumber=&Number;
*是取消运算符,作用是访问指针指定的地址中存储的数据
&是寻址运算符,作用是找到变量值所在的地址
搜索字符串中的一个字符strchr()
strchr(a,b);,a代表字符数组的地址,b是指要查找的字符
返回字符数组中第一个给定字符的地址,如果没有找到给定的字符会返回NULL,它相当于0,表示这个指针没有指向任何对象。
char类型可以和适当的int类型相互转换
strrchr()十分类似于strchr(),它是从字符串的末尾开始查找字符,因此它返回字符串中的最后一个给定字符的地址。
#include <stdio.h> #include <string.h> int main(void) { char str[]="The quick brown fox"; char c='q'; char *pGot_char=NULL; pGot_char=strchr(str,c); char *pGot_char1=strrchr(str,c); if(pGot_char!=NULL) { printf("Character found was %C.",*pGot_char); } if(pGot_char1!=NULL) { printf("Character found was %c.",*pGot_char1); } /* 对null指针的引用会导致游戏崩溃,所以设置if判断 */ return 0; }
这个demo可能有点问题。
在字符串中查找字符串
string()函数,查找一个字符串中的子字符串,返回找到的第一个子字符串的指针。找不到则返回NULL。两个参数:第一个是要搜索的字符串,第二个是要查找的字符串
#include <stdio.h> #include <string.h> int main(void) { char test[]="Every dog has his day"; char word[]="dog"; char *pFound=NULL; pFound=strstr(test,word); printf("%c",*pFound); return 0; }
分析和转换字符串
要检查字符串内部的内容,可以使用在头文件<ctype.h>中声明的标准函数库
转换字符
toupper()将小鞋字母转换成为大写,tolower()将大写字母转换成为小写,都返回转换后的字符,如果大小写正确,就返回原来的字符
toupper(a);
将字符串转换成数值
<stdlib.h>声明了将字符串转换成数值的函数
表中的每一个函数都需要一个指针参数,指向一个字符串或者包含字符串的字符数组,该字符串代表一个数值
#include <stdio.h> #include <stdlib.h> int main(void) { char value_str[]="98.4"; double value=0; value=atof(value_str); printf("%lf",value); return 0; }
宽字符
生命在wchar_t数组中,只需要在前面加上L修饰符号
wchar_t proverb[]=L"A is as good as a wink to a blind horse."
<wchar.h>头文件声明了一些函数来操作宽字符,它们对应于处理一般字符串的函数