关于字符串的功能函数小结
笔者做项目过程中,使用了很多关于字符串的C库中自带功能函数,极大便利了项目流程。再次做一个小结,之后若有增加会继续补充。
所需采用函数
序号 | 函数/描述 |
---|---|
1 | char *strcat(char *dest, const char *src) 【char *strncat(char *dest, const char *src, size_t n)】 功能:连接两个字符串【连接至多n个字节的字符串】 dest目标字符串,src源字符串 返回值:返回目标字符串dest的指针 用法详见例1 |
2 | int strcmp(const char *s1, const char *s2)【int strncmp(const char *s1, const char *s2, size_t n)】 功能:比较两个字符串【比较至多n个字节的字符】 s1目标字符串,s2源字符串,n 字节数量 返回值:如果分别发现s1(或其前n个字节)小于、等于或大于s2,则返回一个小于、等于或大于零的整数。 用法详见例2 |
3 | char *strcpy(char *dest, const char *src)【char *strncpy(char *dest, const char *src, size_t n)】; 功能:复制两个字符串【复制至多n个字节的字符】 dest目标字符串,src源字符串 返回值:返回目标字符串dest的指针 用法详见例3 |
4 | char *strstr(const char *haystack, const char *needle)【char *strchr(const char *s, int c); char *strrchr(const char *s, int c);】; 功能:定位字符串中的子串【定位字符串的字符】 haystack目标字符串,needle子串指针 返回值:strstr函数返回指向找到的子字符串开头的指针,如果找不到子字符串,则返回NULL。【strchr返回指向首次找到字符c的字符开头的指针; strrchr返回指向最后依次找到字符c的字符开头的指针;】 |
5 | char *strtok(char *str, const char *delim);【char *strtok_r(char *str, const char *delim, char **saveptr)】; 功能:从字符串中提取令牌(此处的令牌可理解为每个被分割的子串) 在第一次调用时,str是一个指向要分割的字符串的指针。在后续的调用中,它应该为 NULL ,因为 strtok() 会内部保存上次调用时的位置。delim指向一个字符串的指针,该字符串包含了用于分隔 str 的所有字符。str目标字符串,delim一个包含分隔符的字符串。 strtok 会根据这个字符串的每一个分隔符来分割 str ,使用 strtok() 或 strtok_r() 后,原始字符串 str 会被修改,因为这两个函数会在找到的每个令牌后插入一个空字符('\0')来终止它。 返回值:每次都会返回'\0'前面的值。 用法详见例4 |
6 | char *strerror(int errnum); 功能:这个函数接受一个错误号作为参数,并返回一个指向描述该错误的字符串的指针。 (用的比较少,后面再补充用法与perror有相同之处) |
7 | int atoi(const char *nptr);【 long atol(const char *nptr)】【long long atoll(const char *nptr)】; 功能:把字符串转为整型(长整型/长长整型),从字符串的开头开始解析整数,直到遇到非数字字符为止。 用法详例5 |
8 | double strtod(const char *nptr, char **endptr);【float strtof(const char *nptr, char **endptr)】; 功能:把字符串转为浮点型 nptr 所指向的字符串用法详例子;endptr 会被设置为指向在 nptr 中首次出现不能转换为数字的字符的指针。 |
9 | size_t strlen(const char *s);【size_t strnlen(const char *s, size_t maxlen);】 功能:计算字符串长度【strnlen() 函数只会查看从 s 指向的字符串开始的最多 maxlen 个字符。】 |
10 | char *strsep(char **stringp, const char *delim) 功能:功能与strtok类似,有几点区别: (1)strtok是C标准库中的一个函数,它在POSIX标准中也有定义。这意味着它在各种C和C++编译器中都可用,并且其行为是标准化的。然而,strsep并不是C标准或POSIX标准的一部分,而是GNU C库(glibc)中的一个函数,起源于BSD。 (2)线程安全性。 (3) strsep参数不能用NULL strsep和strtok在功能上是相似的,但在标准化程度、线程安全性、连续分隔符的处理、返回值和参数类型等方面存在差异,需要更深一步学习 用法详见例4 |
例1:strcat&strncat
#include <stdio.h>
#include <string.h>
int main(int argc, char const *argv[])
{
char str1[100] = "Hello";//此处一定要申请一个足够空间的变量,存放str2
char *str2 = "world";
strcat(str1, str2);
printf("change str1 for [%s]\n", str1);
strncat(str1, str2, 4);
printf("change str1 for [%s]\n", str1);
return 0;
}
//输出结果
change str1 for [Helloworld]
change str1 for [Helloworldworl]
例2:strcmp
int main(int argc, char const *argv[])
{
char str1[100] = "Hello";
char *str11 = "Hello";
char *str2 = "Hell";
char *str3 = "Hello";
char *str4 = "Hello1";
printf("result of compare str1 and str2:%d \n", strcmp(str1, str2));
printf("result of compare str11 and str2:%d \n", strcmp(str11, str2));
printf("result of compare str1 and str3:%d \n", strcmp(str1, str3));
printf("result of compare str11 and str3:%d \n", strcmp(str11, str3));
printf("result of compare str1 and str4:%d \n", strcmp(str1, str4));
printf("result of compare str11 and str4:%d \n", strcmp(str11, str4));
return 0;
}
//输出结果
result of compare str1 and str2:111
result of compare str11 and str2:111
//得出结论,数组和字符串常量指针可以直接比较
//str1大于str2,输出大于0,str1等于于str3,输出0,str1小于str4,小于0,
result of compare str1 and str3:0
result of compare str11 and str3:0
result of compare str1 and str4:-49
result of compare str11 and str4:-49
例3:strcpy&strncpy
int main()
{
char str1[100] = "Hello the world";//此处一定要申请一个足够空间的变量,存放str2
char *str2 = "world";
char str11[100] = "Hello the world";//此处一定要申请一个足够空间的变量,存放str2
char *str22 = "world";
strcpy(str1, str2);
printf("copy str1 for [%s]\n", str1);
strncpy(str11, str22, 4);
printf("ncopy str1 for [%s]\n", str11);
return 0;
}
//输出结果
//得到结论,strcpy复制整个源字符串并且会自动添加\0,
//但strncpy不会自动添加\0,如果str1长度大于str2,则只会替换前n个字符,后面的照常
copy str1 for [world]
ncopy str1 for [worlo the world]
例4:strtok&strsep
int main()
{
char student_info[100] = "姓名:李四|性别:男|电话号码:123456789|身份证号码:987654321"; // 以':'和'|'为分隔符分割信息
char *tmp = NULL;
tmp = strtok(student_info, ":"); // 得到第一个“令牌”,即将遇到的第一个‘:’变成‘\0’,tmp得到的是 “姓名”
int i = 1;
while (tmp != NULL)
{
printf("遇到的第%d次分隔符分割结果:%s\n", i, tmp);
i++;
tmp = strtok(NULL, ":|"); // // 得到后续“令牌”,即将遇到的后续的‘:’或者‘|’都改成‘\0’,并返回前值。
}
printf("student_info变成:%s\n", student_info); // 原始的字符串会被改变,被第一次使用的分隔符分割,后面的被‘\0’隔断
char student_info2[100] = "姓名:李四|性别:男|电话号码:123456789|身份证号码:987654321"; // 以':'和'|'为分隔符分割信息
char *tmp2 = NULL;
char *strsep_test = student_info2;
tmp2 = strsep(&strsep_test, ":"); // 得到第一个“令牌”,即将遇到的第一个‘:’变成‘\0’,tmp得到的是 “姓名”
i = 1;
while (tmp2 != NULL)
{
printf("strsep第%d次分割结果:%s\n", i, tmp2);
i++;
tmp2 = strsep(&strsep_test, ":|"); // // 得到后续“令牌”,即将遇到的后续的‘:’或者‘|’都改成‘\0’,并返回前值。
}
printf("student_info变成:%s\n", student_info2); // 原始的字符串会被改变,被第一次使用的分隔符分割,后面的被‘\0’隔断
return 0;
}
//输出结果
遇到的第1次分隔符分割结果:姓名
遇到的第2次分隔符分割结果:李四
遇到的第3次分隔符分割结果:性别
遇到的第4次分隔符分割结果:男
遇到的第5次分隔符分割结果:电话号码
遇到的第6次分隔符分割结果:123456789
遇到的第7次分隔符分割结果:身份证号码
遇到的第8次分隔符分割结果:987654321
student_info变成:姓名
strsep第1次分割结果:姓名
strsep第2次分割结果:李四
strsep第3次分割结果:性别
strsep第4次分割结果:男
strsep第5次分割结果:电话号码
strsep第6次分割结果:123456789
strsep第7次分割结果:身份证号码
strsep第8次分割结果:987654321
student_info变成:姓名
例5:atoi, atol, atoll,strtod, strtof
int main()
{
char *str = "123hello";
printf("%d %ld %lld\n", atoi(str), atol(str), atoll(str)); // 遇到非数字就停止,因此输出123
char *str1 = "123.456hello";
char *endptr;
printf("strtod:%f strtof:%f \n", strtod(str, &endptr), strtof(str, NULL));
printf("接收的首次遇到非数字后面的字符段:%s\n", endptr);
return 0;
}
//输出结果
123 123 123
strtod:123.000000 strtof:123.000000
接收的首次遇到非数字后面的字符段:hello
另外笔者还使用过与内存块处理相关的一些函数,例如memchr、memcmp、memmove、memset,memcpy对于处理字符串也很有用。memchr 用于在内存块中查找字符,memcmp 用于比较内存块,memmove 用于复制内存块(可能重叠),而memset 用于设置内存块的值,memcpy 用于复制内存块的值。后续可能重新整理关于这块内容。