各位读者好,小编现在来浅浅介绍一些C语言库函数中处理字符或字符串的函数。
目录
注意:
1.C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在常量字符串中或者字符数组中。
2.字符串常量适用于那些对它不做修改的字符串函数。
3.以下代码的运行环境均处于32位(x86)系统且为小端机器下运行。
以下函数都可以在https://cplusplus.com/网站中查询到,好的,正文开始:
1.字符串函数
1.求字符串长度
1.strlen
网站查询如下:
strlen函数是一个获取字符串长度的函数,返回C字符串的长度。字符串以 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包含 '\0' )。函数的形参是一个被const修饰的 char*类型的指针变量str,该指针变量str指向所需计算长度的C字符串.
我们要注意以下几点:
1.使用strlen函数需要包含头文件<string.h>;
2.参数指向的字符串必须要以 '\0' 结束;
3.注意函数的返回值为size_t,是无符号的( 易错 );
我们可以来看一个使用strlen函数的实例:
#include<stdio.h>
#include<string.h>
int main()
{
char string[] = "abcd";
size_t len = strlen(string);
printf("%zu\n", len);
return 0;
}
运行结果是4,这里就不展示了。结果是符合预期的!
对于注意事项的第4条,我们可以通过一个代码来方便大家理解,避免踩坑:
#include <stdio.h>
#include<string.h>
int main()
{
const char* str1 = "abcdef";
const char* str2 = "bbb";
if (strlen(str2) - strlen(str1) > 0)
{
printf("str2>str1\n");
}
else
{
printf("srt1>str2\n");
}
return 0;
}
这里打印的是:"str2>str1"。这是为什么呢?
其实也很简单,strlen函数计算str1字符串返回6,计算str2字符串返回3。但这两个返回值都是size_t类型(无符号数)的,这两个size_t类型的数值相减得到的仍然是size_t类型的数值 ,而size_t类型的取值范围应该是大于等于0的整数。所以这里并非数学思想中得到-3这个结果(-3的补码被当成无符号数将会是一个很大的数字:4,294,967,293)。
2.长度不受限制的字符串函数
1.strcpy
网站查询如下:
strcpy函数是一个复制字符串的函数,将源字符串复制到目标数组中,复制包括源字符串的'\0'(并在'\0'处停止)。该函数所需形参分别是char*类型的指向目标空间的指针变量destination和被const修饰的char*类型的指向源字符串的指针变量source。返回值是一个char*类型的指向目标空间的指针变量。
我们要注意以下几点:
1.使用strcpy函数需要包含头文件<string.h>;
2.源字符串必须以 '\0' 结束;
3.会将源字符串中的 '\0' 拷贝到目标空间;
4.目标空间必须足够大,以确保能存放源字符串;
5.目标空间必须可变(目标空间不能为常量字符串);6.源字符串和目标空间在内存中最好不要重叠,否则目标空间大小可能变化;
我们可以来看一个使用strcpy函数的实例:
#include <stdio.h>
#include<string.h>
int main()
{
char string1[20] = "hello woxxx";
char* string2 = "rld";
char* ret = strcpy(string1 + 8, string2);//将"rld"拷贝替换"xxx"
printf("%s\n", ret);
printf("%s\n", string1);
return 0;
}
运行结果分别打印了"rld"和"hello world"。结果是符合预期的!
2.strcat
网站查询如下:
strcat函数是一个将源字符串追加到目标字符串的函数。从目标字符串的'\0'开始向后依次被源字符串的字符覆盖,两者串联形成新的字符串(将源字符串的'\0'也拷贝过去覆盖了,新字符串的末尾包含'\0')。该函数的形参和返回值与上strcpy函数一致,这里不在赘述。
我们要注意以下几点:
1.使用strcpy函数需要包含头文件<string.h>;
2.源字符串必须以 '\0' 结束;
3.目标空间必须有足够的大,能容纳下源字符串的内容;
4.目标空间必须可修改;5.源字符串和目标空间在内存中不要重叠;
我们可以来看一个使用strcat函数的实例:
#include <stdio.h>
#include<string.h>
int main()
{
char string1[20] = "XXX\0XXXXXXXXX";
char string2[] = "abcd";
char*ret=strcat(string1+1, string2);
printf("%s\n", ret);
printf("%s\n", string1);
return 0;
}
运行结果分别打印了"XXabcd"和"XXXabcd"。我们可以分析以下:执行第三条语句时将字符数组string1第2个元素'X'的地址作为目标地址、将字符数组string2作为源字符串。但字符数组string1的第4个元素为'\0',那strcat函数就把这里当成了追加的开始位置,就从这里开始依次追加string2的5个元素(隐藏了'\0'),字符数组string1变成"XXXabcd\0XXXXX\0\0\0\0\0\0\0"。而strcat函数返回目标空间起始地址,即string1+1(指向字符数组string1第2个元素'X'),所以从这个地址开始打印(遇到'\0'停止打印)为"XXabcd"。而string1表示字符数组string1首元素的地址(指向字符数组string1第1个元素'X'),所以从这个地址开始打印(遇到'\0'停止打印)为"XXXabcd"。结果符合预期!
3.strcmp
网站查询如下:
strcmp是一个比较两个字符串的函数。这个函数开始比较每个字符串的第一个字符,如果它们彼此相等,就继续比较每个字符串的下一个字符(即比较两个字符串对应位置上字符的ASCII值大小),直到字符不同或遇到'\0'为止。该函数的形参是两个被const修饰的char*类型的指针变量str1和str2,分别指向两个要比较的字符串。返回值是一个int类型的整数,该值指示字符串之间的关系。
返回值指示两个字符串之间的关系如下:
1.第一个字符串大于第二个字符串,则返回大于0的数字
2.第一个字符串等于第二个字符串,则返回0
3.第一个字符串小于第二个字符串,则返回小于0的数字
我们要注意以下几点:
1.使用strcmp函数需要包含头文件<string.h>;
我们可以来看一个使用strcmp函数的实例:
#include <stdio.h>
#include<string.h>
int main()
{
char string1[20] = "abcde";
char string2[20] = "abcd";
int ret=strcmp(string1, string2);//string1>string2
printf("%d\n", ret);
char arr1[20] = "abcd";
char arr2[20] = "abcd";
int com = strcmp(arr1, arr2);//arr1==arr2
printf("%d\n", com);
char str1[20] = "abc";
char str2[20] = "abcd";
int flag = strcmp(str1, str2);//str1<str2
printf("%d\n", flag);
return 0;
}
运行结果分别打印1、0、-1。 因为以上字符数组元素个数均为20,未初始化部分元素默认为'\0'(ascii码值为0),所以易知结果符合预期!
3.长度受限制的字符串函数
1.strncpy
网站查询如下:
strncpy函数是一个复制字符串的函数。与strcpy函数功能大抵相同,但它规定了复制字符串的字符个数。strncpy函数有三个形参,第三个形参是一个size_t类型的整形num,表示所需复制字符串的字符个数;其他形参和返回值表示含义均与上strcpy函数一致。
我们要注意以下几点:
1.使用strcmp函数需要包含头文件<string.h>;
2.拷贝num个字符从源字符串到目标空间;
3.如果源字符串的长度不大于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个;
4.如果源字符串的长度大于num,则不会在目标的末尾追加'\0',即源字符串的'\0'不会拷贝进源字符串里;5.目标空间必须可变(目标空间不能为常量字符串);
6.源字符串和目标空间在内存中不要重叠;
7.目标空间必须足够大,以确保能存放源字符串;
我们可以来看一个使用strncpy函数的实例:
#include <stdio.h>
#include<string.h>
int main()
{
char string1[20] = "abcdef";
char string2[20] = "xxx";
char* ret = strncpy(string1, string2, 2);//源字符串长度大于num情况
printf("%s\n",ret );
printf("%s\n", string1);
char str1[20] = "abcdef";
char str2[] = "xxx";
char* flag = strncpy(str1, str2, 4);//源字符串长度不大于num情况
printf("%s\n", flag);
printf("%s\n", str1);
return 0;
}
运行结果如下:
结果契合strncpy函数的!
2.strncat
网站查询如下:
strncat函数功能与strcat函数大抵相同,但它规定了从源字符串追加到目标空间的字符个数。strncat函数有三个形参,第三个形参是一个size_t类型的整形num,表示所需复制字符串的字符个数;其他形参和返回值表示含义均与上strcat函数一致。
我们要注意以下几点:
1.使用strcmp函数需要包含头文件<string.h>;
2.该函数追加完num个字符后,会额外追加一个'\0';
3.如果源字符串的长度小于num,则只复制源字符串'\0'之前的内容追加到目标空间,即多追加的部分无效;
5.目标空间必须有足够的大,能容纳下源字符串的内容;
6.目标空间必须可修改;
我们可以来看一个使用strncpy函数的实例:
#include <stdio.h>
#include<string.h>
int main()
{
char string1[20] = "hello wo";
char string2[20] = "rld";
char* ret = strncat(string1, string2, 3);
printf("%s\n",ret );
printf("%s\n", string1);
char str1[20] = "hello b";
char str2[] = "it";
char* flag = strncat(str1, str2, 4);//源字符串长度小于num的情况
printf("%s\n", flag);
printf("%s\n", str1);
return 0;
}
运行结果如下:
结果是符合预期的!
3.strncmp
网站查询如下:
strncmp函数的功能也是大抵与strcmp函数相同,但是它规定了要比较的最大字符数。strncmp函数有三个形参,第三个形参是一个size_t类型的整形num,表示所需比较的最大字符个数;其他形参和返回值表示含义均与上strcmp函数一致。
我们要注意以下几点:
1.使用strcmp函数需要包含头文件<string.h>;
我们可以来看一个使用strcmp函数的实例:
#include <stdio.h>
#include<string.h>
int main()
{
char string1[20] = "hello world";
char string2[20] = "hello bit";
int ret = strncmp(string1, string2, 11);
printf("%d\n",ret );
char str1[20] = "hello bicycle";
char str2[] = "hello bike";
int flag = strncmp(str1, str2, 7);//这里值比较前面7个相同字符
printf("%d\n", flag);
return 0;
}
结果分别打印1和0,符合预期的!
4.字符串查找
1.strstr
网站查询如下:
strstr函数是一个定位子串的函数。strstr函数有两个形参,第1个形参是一个被const修饰的char*类型的指针变量 str1,指向要扫描的字符串;第2个形参是一个被const修饰的char*类型的指针变量str2,指向要匹配的字符串(子串)。返回值是一个char*类型的指针变量,有3种情况:如果能在被扫描的字符串中(定位)找到子串,返回的指针变量指向被扫描字符串中子串第一次出现的位置;如果被扫描字符串中不存在这个子串,返回空指针;如果str2指向'\0',直接返回str1。
我们要注意以下几点:
1.使用strcmp函数需要包含头文件<string.h>;
我们可以来看一个使用strcmp函数的实例:
#include <stdio.h>
#include<string.h>
int main()
{
char str[] = "This is a simple string";
char* pch = strstr(str, "simple");//str中查找字符串"simple"
if (pch != NULL)
strncpy(pch, "sample", 6);//将"sample"复制目标空间pch(指向字符数组str第11个元素's')中
puts(str);//输出复制更改后的str
char string1[]="hello world";
char string2[] = { 0 };
char* ret = strstr(string1, string2);//string2指向'\0'的情况
printf("%s\n", ret);
char arr1[] = "hello bit";
char arr2[] = "hello world";
char* flag = strstr(arr1, arr2);//无法找到子串的情况
printf("%p\n", flag);
return 0;
}
运行结果如下:
结果是符合预期的!
2.strtok
网站查询如下:
strtok函数是一个很特殊的函数,有两个形参:一个char*类型的指针变量str,指向一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记;一个被const修饰的char*类型的指针变量delimiters,指向一个字符串,定义了用作分隔符的字符集合。
如果有一个字符串:"2622077902@qq.com"。那么分隔符集合可以是字符串delimiters:"@.",标记可以是:"2622077902"、"qq"和"com"。没有规定这是唯一分法,分法主要取决于我们想要通过该函数实现什么。
而strtok函数的功能如下:
1.strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
2.strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
3.strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
4.如果字符串中不存在更多的标记,则返回 NULL 指针。
我们要注意以下几点:
1.使用strcmp函数需要包含头文件<string.h>;
2.strtok函数形参str指向的空间必须可修改;
我们用一个代码来理解该函数的功能:
#include <stdio.h>
#include<string.h>
int main()
{
char str[] = "2622077902@qq.com";
const char* delimiters = "@.";
char* ret = strtok(str, delimiters);
printf("%s\n", ret);//第一次打印
ret = strtok(NULL, delimiters);
printf("%s\n", ret);//第二次打印
ret = strtok(NULL, delimiters);
printf("%s\n", ret);//第三次打印
ret = strtok(NULL, delimiters);
printf("%s\n", ret);//第四次打印
printf("%p\n", ret);//第五次打印
printf("%s\n", str);//第六次打印
return 0;
}
我们来看结果:
第一次执行strtok函数时, 第一个参数不为 NULL ,函数将找到str中第一个标记(2622077902),并将分隔符'@'修改成'\0',并保存标记在字符串中的位置,且返回一个指向这个标记的指针赋值给ret,打印的自然是2622077902;
第二次执行strtok函数时,第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记(qq),并将分隔符'.'修改成'\0',并保存标记在字符串中的位置,且返回一个指向这个标记的指针赋值给ret,打印的自然是qq;
第三次执行strtok函数时,第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记(com),这里没有更多分隔符可修改成'\0',而且com末尾本身就是'\0',所以不改分隔符。并保存标记在字符串中的位置,且返回一个指向这个标记的指针赋值给ret,打印的自然是com;
第四次执行strtok函数时,第一个参数为NULL,函数将在同一个字符串中被保存的位置开始,查找下一个标记,但字符串中不存在更多的标记,所以返回 NULL 指针,第四次和第五次打印自然为(null)和00000000。
第六次打印易知打印为2622077902,这里主要是想印证strtok函数会改变被操作的字符串(第一次执行strtok时分隔符'@'被修改成'\0'导致只能打印出2622077902)。
我们还可以根据strtok函数和for循环的特点优化上面代码:
#include <stdio.h>
#include<string.h>
int main()
{
char str[] = "2622077902@qq.com";
const char* delimiters = "@.";
char* ret = NULL;
for (ret = strtok(str, delimiters); ret != NULL; ret = strtok(NULL, delimiters))
{
printf("%s\n", ret);//前三次打印
}
ret = strtok(NULL, delimiters);
printf("%s\n", ret);//第四次打印
printf("%p\n", ret);//第五次打印
printf("%s\n", str);//第六次打印
return 0;
}
这里就不分析了,跟上面分析一致。
5.错误信息报告
1.strerror
网站查询如下:
strerror函数是将错误码翻译成错误信息,返回错误信息的字符串的起始地址。该函数的形参是一个int型的整形errnum。
C语言中使用库函数的时候,如果发生错误,就会将错误码放在一个全局变量errno里面。当我们使用库函数发生错误时,如不知道为什么发生错误,就可以将errno传参给strerror函数,在根据strerror返回的起始地址打印出错误信息。
我们要注意以下几点:
1.使用strcmp函数需要包含头文件<string.h>;
我们可以来看一个使用strncpy函数的实例:
//打开文件的例子
/*fopen函数以读的形式打开文件。如果文件存在,打开成功;
如果文件不存在,打开失败,返回空指针。*/
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main()
{
FILE* pf = fopen("add.txt", "r");
if (pf == NULL)
{
printf("打开文件失败,原因时:%s\n", strerror(errno));
}
else
{
printf("打开文件成功\n");
}
return 0;
}
在以上代码的当前文件夹中是没有"add.txt"文件的,看结果:
好的,结果符合预期!
2.字符函数
1.字符分类函数
函数 | 如果他的参数符合下列条件就返回真,否则返回0 |
iscntrl | 任何控制字符 |
isspace | 空白字符:空格‘ ’,换页‘\f’,换行'\n',回车‘\r’,制表符'\t'或者垂直制表符'\v' |
isdigit | 十进制数字 0~9 |
isxdigit | 十六进制数字,包括所有十进制数字,小写字母a~f,大写字母A~F |
islower | 小写字母a~z |
isupper | 大写字母A~Z |
isalpha | 字母a~z或A~Z |
isalnum | 字母或者数字,a~z,A~Z,0~9 |
ispunct | 标点符号,任何不属于数字或者字母的图形字符(可打印) |
isgraph | 任何图形字符 |
isprint | 任何可打印字符,包括图形字符和空白字符 |
这些函数比较简单易懂,这里就不过多介绍了,有兴趣可以去网站查询哈!
2.字符转换函数
1.tolower
tolower函数是一个将大写字母转换成小写字母的函数。
2.toupper
toupper函数是一个将小写字母转换成大小字母的函数。
#include <stdio.h>
#include <ctype.h>//isupper函数和tolower函数所需头文件
int main()
{
int i = 0;
char str[] = "Test String.\n";
char c;
while (str[i])//循环遍历字符数组str
{
c = str[i];//字符数组str元素依次赋值给字符变量c
if (isupper(c))//如字符变量c为大写字母
c = tolower(c);//将大写字母转换成小写字母
putchar(c);//输出字符变量c
i++;
}
return 0;
}
结果如下:
3.ending:
感谢阅读,跪求点赞。如有不足,恳请斧正!