24 C 语言常用的字符串处理函数详解:strlen、strcat、strcpy、strcmp、strchr、strrchr、strstr、strtok
目录
1 strlen
1.1 函数原型
1.2 功能说明
1.3 案例演示
1.4 注意事项
2 strcat
2.1 函数原型
2.2 功能说明
2.3 案例演示
2.4 注意事项
3 strcpy
3.1 函数原型
3.2 功能说明
3.3 案例演示
3.4 注意事项
4 strcmp
4.1 函数原型
4.2 功能说明
4.3 案例演示
4.4 注意事项
5 strchr
5.1 函数原型
5.2 功能说明
5.3 案例演示
5.4 注意事项
6 strrchr
6.1 函数原型
6.2 功能说明
6.3 案例演示
6.4 注意事项
7 strstr
7.1 函数原型
7.2 功能说明
7.3 案例演示
7.4 注意事项
8 strtok
8.1 函数原型
8.2 功能说明
8.3 案例演示
8.4 注意事项
9 总结对比表
1 strlen
1.1 函数原型
strlen 函数是 C 语言标准库中的一个函数,用于计算字符串的长度(不包括终止的空字符 '\0')。其函数原型定义在 <string.h> 头文件中。
#include <string.h>
size_t strlen(const char *str);
- 参数:const char *str,指向以 null 结尾的字符串的指针。
- 返回值:size_t,表示字符串的长度,即不包括终止的空字符 '\0' 的字符数。最好使用 %zu 进行打印输出。
1.2 功能说明
strlen 函数遍历传入的字符串,直到遇到第一个空字符 '\0' 为止,并返回遍历过程中遇到的字符数(不包括 '\0')。这个函数对于处理 C 语言中的字符串非常有用,因为 C 语言中的字符串是以空字符 '\0' 结尾的字符数组。
1.3 案例演示
#include <stdio.h>
#include <string.h>int main()
{char str[] = "Hello,World!";printf("字符串 '%s' 的长度是:%zu,sizeof(str)=%zu\n", str, strlen(str), sizeof(str));// 演示空字符串的情况char emptyStr[] = "";printf("空字符串 '%s' 的长度是:%zu,sizeof(emptyStr)=%zu\n", emptyStr, strlen(emptyStr), sizeof(emptyStr));// 演示包含空格的字符串char spaceStr[] = "Hello World";printf("包含空格的字符串 '%s' 的长度是:%zu,sizeof(spaceStr)=%zu\n", spaceStr, strlen(spaceStr), sizeof(spaceStr));return 0;
}
输出结果如下所示:
1.4 注意事项
不包含终止符:strlen 返回的长度不包括字符串末尾的空字符 '\0'。
参数检查:使用 strlen 时,应确保传入的指针不是 NULL,否则会导致未定义行为(通常是程序崩溃)。
性能考虑:由于 strlen 需要遍历整个字符串直到找到 '\0',因此其性能与字符串的长度成正比。在处理非常长的字符串时,应考虑性能影响。
修改字符串:虽然 strlen 的参数是 const char *,意味着理论上不应修改字符串,但在实际编程中,确保在调用 strlen 后不修改字符串,因为后续操作可能依赖于字符串的原始内容。
替代方案:在某些情况下,如果已知字符串的最大长度,或者字符串存储在固定大小的数组中,可以考虑使用数组的大小作为长度,而不是调用 strlen。这可以避免运行时开销,并可能提高性能。
安全性:在处理来自不可信源的字符串时,应确保字符串不会超出预期的长度,以避免缓冲区溢出等安全问题。
2 strcat
2.1 函数原型
strcat 函数是 C 语言标准库中的一个函数,用于将两个字符串连接起来。其函数原型定义在 <string.h> 头文件中。
#include <string.h>
char *strcat(char *dest, const char *src);
- 参数:
- char *dest:指向目标字符串的指针,即要连接到的字符串。这个字符串必须有足够的空间来存储两个字符串连接后的结果。
- const char *src:指向源字符串的指针,即要连接到目标字符串末尾的字符串。
- 返回值:返回指向目标字符串(dest)的指针。
2.2 功能说明
strcat 函数将 src 字符串(终止的空字符 '\0' 之前的所有字符)追加到 dest 字符串的末尾(原来存放 '\0' 的位置),并自动在结果字符串的末尾添加一个新的空字符 '\0'。如果 dest 和 src 指向的字符串重叠,则行为是未定义的。
2.3 案例演示
#include <stdio.h>
#include <string.h>int main()
{char dest[20] = "Hello, ";const char *src = "World!";// 使用 strcat 连接字符串strcat(dest, src);// 输出连接后的字符串printf("连接后的字符串是:%s\n", dest);return 0;
}
输出结果如下所示:
字符串初始化完成后的存储情况,如下所示:
使用 strcat 追加字符串后,目标字符串内容如下所示:
2.4 注意事项
空间足够:确保目标字符串 dest 有足够的空间来存储两个字符串连接后的结果,包括额外的终止空字符 '\0'。如果空间不足,将导致缓冲区溢出,这是常见的安全问题。
重叠字符串:如果 dest 和 src 指向的字符串内存区域重叠,则 strcat 的行为是未定义的。在这种情况下,应使用 strncat 或其他安全的字符串处理函数。
空字符串:如果 src 是空字符串(即仅包含 '\0'),则 dest 字符串不会改变,但函数仍然会返回 dest 的指针。
返回值:虽然 strcat 的返回值通常不是必需的,但了解它返回的是 dest 的指针可以在某些情况下简化代码。
安全性:在处理来自不可信源的字符串时,应特别小心,以避免缓冲区溢出等安全问题。考虑使用 strncat 或其他更安全的字符串处理函数。
终止符:strcat 会自动在连接后的字符串末尾添加一个新的终止空字符 '\0'。这是确保字符串正确结束的关键。
性能:strcat 需要遍历 dest 字符串以找到其末尾的空字符,然后才能开始追加 src 字符串。因此,其性能与 dest 字符串的长度成正比。在处理非常长的字符串时,应考虑性能影响。
3 strcpy
3.1 函数原型
strcpy 函数是 C 语言标准库中的一个函数,用于复制字符串。它的函数原型定义在 <string.h> 头文件中。
#include <string.h>
char *strcpy(char *dest, const char *src);
- 参数:
- dest:目标字符串的指针,即要复制到的字符串的起始地址。
- src:源字符串的指针,即要复制的字符串的起始地址。
- 返回值:函数返回 dest 的指针。
3.2 功能说明
strcpy 函数将 src 指向的字符串(包括终止的 '\0' 字符)复制到 dest 指向的数组中,包括终止的空字符。因此,dest 指向的数组必须足够大,以容纳要复制的字符串,包括终止的空字符。如果 dest 和 src 重叠,则 strcpy 的行为是未定义的。
3.3 案例演示
#include <stdio.h>
#include <string.h>int main()
{char src[] = "Hello, World!";char dest[50]; // 确保有足够的空间来存放复制的字符串// 使用 strcpy 函数复制字符串strcpy(dest, src);// 输出复制的字符串printf("复制的字符串是: %s\n", dest);return 0;
}
输出结果如下所示:
3.4 注意事项
缓冲区溢出:如果目标数组 dest 的大小不足以容纳源字符串 src(包括终止的空字符),则会发生缓冲区溢出,这可能导致未定义的行为,包括程序崩溃或安全漏洞。
重叠内存:如果 dest 和 src 指向的内存区域重叠,则 strcpy 的行为是未定义的。在这种情况下,应使用 memmove 函数,它总是安全地处理重叠内存。
字符串终止:strcpy 会复制源字符串中的终止空字符('\0'),因此目标字符串也会被正确地终止。
返回值:虽然 strcpy 的返回值(dest 的指针)在大多数情况下不是必需的,但它可以用于链式调用或错误检查(尽管对于 strcpy 来说,错误检查通常是通过确保目标缓冲区足够大来实现的)。
安全性:由于 strcpy 不检查目标缓冲区的大小,因此建议使用更安全的字符串复制函数,如 strncpy(尽管 strncpy 有其自己的限制和注意事项)。对于需要安全复制字符串的场景,考虑使用 strlcpy(如果可用)或手动实现一个安全的复制函数。
4 strcmp
4.1 函数原型
strcmp 函数是 C 语言标准库中的一个函数,用于比较两个字符串。其函数原型定义在 <string.h> 头文件中。
#include <string.h>
int strcmp(const char *str1, const char *str2);
- 参数:
- const char *str1:指向第一个要比较的字符串的指针。
- const char *str2:指向第二个要比较的字符串的指针。
- 返回值:
- 如果 str1 和 str2 字符串相等,则返回 0。
- 如果 str1 在字典序(基于字符的 ASCII 值)上小于 str2,则返回一个小于 0 的值。
- 如果 str1 在字典序(基于字符的 ASCII 值)上大于 str2,则返回一个大于 0 的值。
4.2 功能说明
strcmp 函数逐个字符地比较两个字符串,直到出现不同的字符或遇到字符串的终止符 '\0'。如果两个字符串在所有对应位置上的字符都相同,则认为这两个字符串相等。如果在某个位置上,str1 的字符在 ASCII 码表中小于 str2 的对应字符,则认为 str1 在字典序上小于 str2;反之亦然。
4.3 案例演示
#include <stdio.h>
#include <string.h>int main()
{char str1[] = "Hello";char str2[] = "World";char str3[] = "Hello";// 比较 str1 和 str2int result1 = strcmp(str1, str2);if (result1 < 0){printf("'%s' 在字典序上小于 '%s'\n", str1, str2);}else if (result1 > 0){printf("'%s' 在字典序上大于 '%s'\n", str1, str2);}else{printf("'%s' 和 '%s' 相等\n", str1, str2);}// 比较 str1 和 str3int result2 = strcmp(str1, str3);if (result2 == 0){printf("'%s' 和 '%s' 相等\n", str1, str3);}return 0;
}
输出结果如下所示:
4.4 注意事项
大小写敏感:strcmp 函数是大小写敏感的,即 'A' 和 'a' 被视为不同的字符。
空字符串:如果任一字符串为空(即仅包含终止符 '\0',ASCII 值是 0),则非空字符串在字典序上大于空字符串。
未定义行为:如果任一指针为 NULL,则 strcmp 的行为是未定义的。在实际使用中,应确保传入的指针是有效的。
返回值的使用:虽然返回值可以用于判断两个字符串的相对大小,但直接比较返回值与 0、<0 或 >0 时应小心,因为具体的返回值(除了 0 之外)是未指定的,并且可能因实现而异。
安全性:strcmp 本身不涉及内存分配或修改字符串内容,因此从安全性的角度来看,它相对安全。然而,在使用 strcmp 时仍需注意确保传入的字符串指针是有效的,并且不会越界访问内存。
5 strchr
5.1 函数原型
strchr 函数是 C 语言标准库中的一个函数,用于在字符串中查找第一次出现的指定字符。其函数原型定义在 <string.h> 头文件中。
#include <string.h>
char *strchr(const char *str, int c);
- 参数:
- const char *str:指向要搜索的字符串的指针。
- int c:要搜索的字符(以 int 形式传递,以便可以传递 EOF 等特殊值,但通常传递字符的 ASCII 值)。
- 返回值:
- 如果找到字符 c,则返回指向该字符在字符串中第一次出现的位置的指针。
- 如果未找到字符 c,则返回 NULL。
5.2 功能说明
strchr 函数遍历字符串 str,查找字符 c 的第一次出现。如果找到该字符,函数将返回一个指向该字符的指针;如果未找到,则返回 NULL。注意,搜索是区分大小写的。
5.3 案例演示
#include <stdio.h>
#include <string.h>int main()
{char str[] = "Hello, World!";char *pos;// 查找字符 'o'pos = strchr(str, 'o');if (pos != NULL){printf("找到字符 'o',位置:%d\n", pos - str + 1); // 输出位置(基于 1 的索引)}else{printf("未找到字符 'o'。\n");}// 查找字符 'W'(注意大小写)pos = strchr(str, 'W');if (pos != NULL){printf("找到字符 'W',位置:%d\n", pos - str + 1); // 输出位置(基于 1 的索引)}else{printf("未找到字符 'W'。\n");}// 查找不存在的字符pos = strchr(str, 'x');if (pos == NULL){printf("未找到字符 'x'。\n");}return 0;
}
输出结果如下所示:
5.4 注意事项
大小写敏感:strchr 函数在搜索时是区分大小写的。
返回值类型:尽管 strchr 的参数是 const char *,但返回类型是 char *。这允许调用者通过返回的指针修改字符串(尽管修改原始字符串指针指向的内容可能不是个好主意,因为它可能违反了原始数据的不可变性假设)。然而,如果原始字符串是字面量或位于只读内存区域,尝试修改返回的字符串可能会导致未定义行为。
空字符串和 NULL 指针:如果 str 是空字符串(即仅包含终止的 '\0'),则 strchr 仅在未搜索到字符时返回 NULL。如果 str 是 NULL,则 strchr 的行为是未定义的,因此在调用之前应确保 str 不是 NULL。
字符参数:尽管 strchr 的第二个参数是 int 类型,但通常传递的是字符的 ASCII 值或字符常量。这允许传递 EOF 或其他特殊值,但在搜索字符串字符时并不常用。
效率:strchr 函数通常实现为线性搜索,即从头开始逐个字符地检查字符串,直到找到指定的字符或到达字符串的末尾。因此,在最坏的情况下,其时间复杂度为 O(n),其中 n 是字符串的长度。
6 strrchr
6.1 函数原型
strrchr 函数是 C 语言标准库中的一个函数,用于在字符串中查找最后一次出现的指定字符。其函数原型定义在 <string.h> 头文件中。
#include <string.h>
char *strrchr(const char *str, int c);
- 参数:
- const char *str:指向要搜索的字符串的指针。
- int c:要搜索的字符(以 int 形式传递,但通常传递的是字符的 ASCII 值)。
- 返回值:
- 如果找到字符 c,则返回指向该字符在字符串中最后一次出现的位置的指针。
- 如果未找到字符 c,则返回 NULL。
6.2 功能说明
strrchr 函数遍历字符串 str,从字符串的末尾开始向前搜索,查找字符 c 的最后一次出现。如果找到该字符,函数将返回一个指向该字符的指针;如果未找到,则返回 NULL。注意,搜索是区分大小写的。
6.3 案例演示
#include <stdio.h>
#include <string.h>int main()
{char str[] = "Hello, World! This is a test.";char *pos;// 查找字符 'o'pos = strrchr(str, 'o');if (pos != NULL){printf("找到字符 'o',最后一次出现的位置:%d\n", pos - str + 1); // 输出位置(基于 1 的索引)}else{printf("未找到字符 'o'。\n");}// 查找字符 't'(注意字符串中有多个't')pos = strrchr(str, 't');if (pos != NULL){printf("找到字符 't',最后一次出现的位置:%d\n", pos - str + 1); // 输出位置(基于 1 的索引)}else{printf("未找到字符 't'。\n");}// 查找不存在的字符pos = strrchr(str, 'x');if (pos == NULL){printf("未找到字符 'x'。\n");}return 0;
}
输出结果如下所示:
6.4 注意事项
大小写敏感:strrchr 函数在搜索时是区分大小写的。
返回值类型:尽管 strrchr 的参数是 const char *,但返回类型是 char *。这允许调用者通过返回的指针修改字符串(尽管这可能不是个好主意,特别是如果原始字符串是字面量或位于只读内存区域)。
空字符串和 NULL 指针:如果 str 是空字符串(即仅包含终止的 '\0'),则 strrchr 仅在未搜索到字符时返回 NULL。如果 str 是 NULL,则 strrchr 的行为是未定义的,因此调用前必须确保 str 不是 NULL。
字符参数:尽管 strrchr 的第二个参数是 int 类型,但通常传递的是字符的 ASCII 值或字符常量。
效率:与 strchr 类似,strrchr 函数通常实现为从字符串末尾开始的线性搜索,其时间复杂度在最坏情况下为 O(n),其中 n 是字符串的长度。然而,由于它从末尾开始搜索,对于某些特定情况(如查找字符串末尾的特定字符),它可能比从头开始的搜索更高效。
7 strstr
7.1 函数原型
strstr 函数是 C 语言标准库中的一个函数,用于在字符串中查找第一次出现的子串。其函数原型定义在 <string.h> 头文件中。
#include <string.h>
char *strstr(const char *str1, const char *str2);
- 参数:
- const char *str1:指向要搜索的字符串(主字符串)的指针。
- const char *str2:指向要搜索的子串的指针。
- 返回值:
- 如果找到子串 str2,则返回指向 str1 中子串 str2 第一次出现的位置的指针。
- 如果未找到子串 str2,则返回 NULL。
7.2 功能说明
strstr 函数遍历字符串 str1,查找第一次出现的与 str2 完全相同的子串。如果找到这样的子串,函数将返回一个指向 str1 中该子串起始位置的指针;如果未找到,则返回 NULL。搜索是区分大小写的。
- 如果 str2 是空字符串(即仅包含终止的 '\0'),则 strstr 将返回 str1 的起始地址,因为空字符串是任何字符串的子串。
- 如果 str1 或 str2 是 NULL,则 strstr 的行为是未定义的,因此在调用之前应确保这两个参数都不是 NULL。
7.3 案例演示
#include <stdio.h>
#include <string.h>int main()
{char str1[] = "Hello, World! This is a test.";char str2[] = "World";char *pos;// 查找子串 "World"pos = strstr(str1, str2);if (pos != NULL){printf("找到子串 '%s',位置:%d\n", str2, pos - str1 + 1); // 输出位置(基于 1 的索引)}else{printf("未找到子串 '%s'。\n", str2);}// 查找不存在的子串char str3[] = "xyz";pos = strstr(str1, str3);if (pos == NULL){printf("未找到子串 '%s'。\n", str3);}// 查找空子串(虽然不常见,但技术上可行)char str4[] = "";pos = strstr(str1, str4);if (pos != NULL){printf("找到空子串,位置:%d(即字符串开头)\n", pos - str1 + 1); // 输出位置(基于 1 的索引)}return 0;
}
输出结果如下所示:
7.4 注意事项
大小写敏感:strstr 函数在搜索时是区分大小写的。
返回值类型:尽管 strstr 的参数是 const char *,但返回类型是 char *。这允许调用者通过返回的指针访问或修改子串(但请注意,如果原始字符串是字面量或位于只读内存区域,则不应修改它)。然而,修改返回的字符串可能会影响原始字符串的其余部分,因为它们是连续存储的。
空字符串和 NULL 指针:如果 str2 是空字符串(即仅包含终止的 '\0'),则 strstr 将返回 str1 的起始地址,因为空字符串是任何字符串的子串。如果 str1 或 str2 是 NULL,则 strstr 的行为是未定义的,因此在调用之前应确保这两个参数都不是 NULL。
效率:strstr 函数的实现通常涉及两个字符串的逐字符比较,直到找到匹配的子串或遍历完 str1。在最坏的情况下,其时间复杂度为 O(n*m),其中 n 是 str1 的长度,m 是 str2 的长度。然而,对于许多实际应用,由于 str2 通常较短,因此效率是可以接受的。
重叠字符串:如果 str2 是 str1 的一个后缀,并且两个字符串在内存中是重叠的(尽管这种情况在标准 C 字符串操作中不常见),则 strstr 仍然能够正确找到子串。但是,在修改返回的字符串时要特别小心,以避免破坏原始字符串的其余部分。
8 strtok
8.1 函数原型
strtok 函数是 C 语言标准库中的一个函数,用于分割字符串为一系列标记(tokens)。其函数原型定义在 <string.h> 头文件中,并需要一个额外的 <stdlib.h> 头文件来访问 NULL(在某些实现中可能不是必需的,但出于清晰和可移植性考虑,建议包含)。
#include <string.h>
// 可能还需要 #include <stdlib.h>,尽管在函数原型中未直接使用
char *strtok(char *str, const char *delim);
- 参数:
- char *str:指向要分割的字符串的指针。在首次调用时,它应该是一个指向要分割的字符串的指针。在后续的调用中,它应该是 NULL,以便 strtok 继续从上次停止的地方开始分割。
- const char *delim:指向一个字符串,包含用作分隔符的字符集合。
- 返回值:返回指向下一个标记的指针。如果没有更多的标记,则返回 NULL。
8.2 功能说明
strtok 函数通过扫描 str 指向的字符串来查找由 delim 字符串中任一字符分隔的标记(token)。找到的第一个标记由函数返回,并在原始字符串中用 \0 替换分隔符。在后续的调用中,通过将 str 设置为 NULL,strtok 会继续从上次停止的地方扫描剩余的字符串。
strtok 函数在字符串中遇到连续的分隔符时,它会将这些连续的分隔符都视为单个分隔符,并在结果中忽略它们(即不会将连续分隔符视为多个分隔符来产生多个空标记)。
8.3 案例演示
#include <stdio.h>
#include <string.h>int main()
{char str[] = "Hello, World! This is a test.";const char delimiters[] = " ,.!";// 返回指向下一个标记的指针。如果没有更多的标记,则返回 NULLchar *token;// 获取第一个标记token = strtok(str, delimiters);while (token != NULL){printf("标记:%s\n", token);// 获取下一个标记token = strtok(NULL, delimiters);}// 注意:此时 str 已被 strtok 修改,分隔符被替换为 '\0'// 如果需要原始字符串,应保留一份副本return 0;
}
输出结果如下所示:
字符串初始化完成后的存储情况,如下所示:
使用 strtok 分割字符串后,分隔符被替换为 '\0',源字符串内容如下所示:
如果两个标记之间只有分隔符(没有非分隔符字符),那么 strtok 会在遇到第一个分隔符时停止,并返回当前的标记。然而,在紧接着的下一次调用中(仍然传递 NULL),由于所有分隔符都已被跳过,并且没有找到新的非分隔符字符来开始新的标记,strtok 将返回 NULL,表示没有更多的标记可供读取。
例如,在上述代码中,World 和 This 之间有一个感叹号和一个空格作为分隔符,但 strtok 不会为这些分隔符都生成空标记。它只会将它们视为分隔 World 和 This 这两个标记的边界。因此,strtok 会返回 "Hello" 作为第一个标记,然后是 "World",接着是 "This",依此类推,直到字符串结束。
8.4 注意事项
修改原始字符串:strtok 会修改传入的字符串,用 \0 替换分隔符。如果需要保留原始字符串,请在使用 strtok 之前创建一份副本。
线程安全性:strtok 不是线程安全的,因为它使用静态变量来存储对原始字符串的引用和上次分割的位置。在多线程环境中,如果需要同时分割多个字符串,应考虑使用 strtok_r(在 POSIX 兼容系统中可用),它是 strtok 的可重入版本。
分隔符字符串:分隔符字符串中的字符可以是任何字符,包括空格、标点符号等。但是,要注意分隔符字符串中的字符是逐个检查的,而不是作为整体字符串来搜索。
连续分隔符:如果字符串中有连续的分隔符,strtok 会将它们视为单个分隔符,并跳过它们,只返回一个空标记(如果请求的话)。如果两个标记之间只有分隔符,则在这些分隔符之后调用 strtok 时会立即返回 NULL,因为没有更多的标记可以读取。
空字符串:如果 str 是一个空字符串,strtok 将立即返回 NULL,因为没有标记可以提取。
NULL 参数:在首次调用 strtok 之后,必须通过将 str 设置为 NULL 来继续分割操作,而不是再次传递原始字符串的指针。
9 总结对比表
函数名称 | 函数原型 | 功能描述 | 关键点 |
---|---|---|---|
strlen | #include <string.h> size_t strlen(const char *str); | 计算字符串 str 的长度,不包括终止的空字符 \0。 | 返回值类型是 size_t(%zu 打印输出),表示无符号整数。 |
strcat | #include <string.h> char *strcat(char *dest, const char *src); | 将 src 字符串追加到 dest 字符串的末尾,并在结果字符串的末尾添加一个空字符 \0。 | dest 必须有足够的空间来容纳结果字符串。如果 dest 和 src 重叠,行为未定义。 |
strcpy | #include <string.h> char *strcpy(char *dest, const char *src); | 将 src 字符串复制到 dest,包括终止的空字符 \0。 | dest 必须有足够的空间来容纳 src 字符串。如果 dest 和 src 重叠,行为未定义。 |
strcmp | #include <string.h> int strcmp(const char *str1, const char *str2); | 比较两个字符串 str1 和 str2。 | 返回值:如果 str1 和 str2 相等,返回 0;如果 str1 小于 str2,返回负数;如果 str1 大于 str2,返回正数。 |
strchr | #include <string.h> char *strchr(const char *str, int c); | 查找字符串 str 中第一次出现的字符 c,并返回该字符的指针。如果未找到,则返回 NULL。 | c 是一个整数,可以是任何 ASCII 值,包括 \0。 |
strrchr | #include <string.h> char *strrchr(const char *str, int c); | 查找字符串 str 中最后一次出现的字符 c,并返回该字符的指针。如果未找到,则返回 NULL。 | c 是一个整数,可以是任何 ASCII 值,包括 \0。 |
strstr | #include <string.h> char *strstr(const char *str1, const char *str2); | 查找字符串 str2 在字符串 str1 中第一次出现的位置,并返回该位置的指针。如果未找到,则返回 NULL。 | str2 不能是空字符串。 |
strtok | #include <string.h> | 将字符串 str 按照分隔符 delim 分割成多个子字符串。每次调用返回下一个子字符串的指针,并在原始字符串中用 \0 替换分隔符。 | 第一次调用时,str 应该是完整的字符串;后续调用时,str 应该传入 NULL。 |
相关文章:

24 C 语言常用的字符串处理函数详解:strlen、strcat、strcpy、strcmp、strchr、strrchr、strstr、strtok
目录 1 strlen 1.1 函数原型 1.2 功能说明 1.3 案例演示 1.4 注意事项 2 strcat 2.1 函数原型 2.2 功能说明 2.3 案例演示 2.4 注意事项 3 strcpy 3.1 函数原型 3.2 功能说明 3.3 案例演示 3.4 注意事项 4 strcmp 4.1 函数原型 4.2 功能说明 4.3 案例演示 …...

数据驱动农业——农业中的大数据
橙蜂智能公司致力于提供先进的人工智能和物联网解决方案,帮助企业优化运营并实现技术潜能。公司主要服务包括AI数字人、AI翻译、埃域知识库、大模型服务等。其核心价值观为创新、客户至上、质量、合作和可持续发展。 橙蜂智农的智慧农业产品涵盖了多方面的功能&…...

学习《分布式》必须清楚的《CAP理论》
分布式的理论基础CAP理论 当学习分布式的redis、mq等中间件时,都会看到有提到CAP。 CAP理论是学习分布式必备的一个概念知识点。 CAP理论由三个特性组成,分别是一致性(Consistency)、可用性(Availability࿰…...

navicat无法连接远程mysql数据库1130报错的解决方法
出现报错:1130 - Host ipaddress is not allowed to connect to this MySQL serve navicat,当前ip不允许连接到这个MySQL服务 解决当前ip无法连接远程mysql的方法 1. 查看mysql端口,并在服务器安全组中放开相应入方向端口后重启服务器 sud…...

JetPack01- LifeCycle 监听Activity或Fragment的生命周期
前提 阅读本文的前提是要了解观察者模式。本文没有讲述反射相关的内容,功能中有使用反射。 简介 监听Activity/Fragment的生命周期,使用观察者模式,Activity/Fragment是被观察者。 监听的生命周期有onCreate、onStart、onResume、onPause…...

OpenCSG推出StarShip SecScan:AI驱动的软件安全革新
OpenCSG 导读 如今,IT 技术迅速发展,软件安全不仅是企业稳健运营的基础,更是整个社会经济体系安全的保障。加强软件安全,尤其是在开发阶段识别和修补漏洞,是企业必须重视的问题。国际数据公司(IDC…...

占道经营检测-目标检测数据集(包括VOC格式、YOLO格式)
占道经营检测-目标检测数据集(包括VOC格式、YOLO格式) 数据集: 链接:https://pan.baidu.com/s/1e4Ydsb7FaUeWcQ-76ClTpQ?pwdq7n7 提取码:q7n7 数据集信息介绍: 共有 1143 张图像和一一对应的标注文件 标…...

828华为云征文 | 云服务器Flexus X实例:RAG 开源项目 FastGPT 部署,玩转大模型
目录 一、FastGPT 简介 二、FastGPT 部署 2.1 下载启动文件 2.2 开放端口权限 2.3 启动 FastGPT 三、FastGPT 运行 3.1 登录 FastGPT 3.2 知识库 3.3 应用 四、总结 本篇文章主要通过 Flexus云服务器X实例 部署 RAG 开源项目 FastGPT,通过 FastGPT 可以使…...

MySQL之基本查询(一)(insert || select)
目录 一、表的增删查改 二、表的增加insert 三、表的读取select where 条件子句 结果排序 筛选分页结果 一、表的增删查改 我们平时在使用数据库的时候,最重要的就是需要对数据库进行各种操作。而我们对数据库的操作一般来说也就是四个操作,CRUD :…...

基于深度学习的多智能体协作
基于深度学习的多智能体协作是一种通过多个智能体相互协作完成复杂任务的框架,利用深度学习技术来优化智能体之间的合作与决策过程。多智能体系统广泛应用于自动驾驶、机器人群体、游戏AI、资源调度、无人机编队等领域,其中每个智能体通常具有自主性&…...

Nmap网络扫描器基础功能介绍
怎么快速知道网络中存在哪些设备呢?我们可以借用扫描工具Nmap来实现这个功能。 下载 Windows系统可以前往Nmap官网下载安装包。 Linux使用对应的包管理器可以直接安装,命令如下 # Debian/Ubuntu apt install nmap# RedHat/Fedora yum install nmap …...

idea 编辑器常用插件集合
SequenceDiagram 用于生成时序图的插件,支持一键生成功能。 使用:选择某个具体的方法,点击右键菜单,选择“Sequence Diagram” 便可生成相应的时序图 例子: 效果: Code Iris Code Iris可以根据代码自动…...

如何优化Java商城系统的代码结构
前言 优化Java商城系统的代码结构可以提高代码的可维护性、可读性和性能。以下是一些建议: 一、模块化设计 将系统拆分为多个模块,每个模块负责特定的功能。例如,可以将用户管理、商品管理、订单管理等功能分别放在不同的包中。 二、分层…...

两数之和、三数之和、四数之和
目录 两数之和 题目链接 题目描述 思路分析 代码实现 三数之和 题目链接 题目描述 思路分析 代码实现 四数之和 题目链接 题目描述 思路分析 代码实现 两数之和 题目链接 LCR 179. 查找总价格为目标值的两个商品 - 力扣(LeetCode) 题目…...

这几个方法轻松压缩ppt文件大小,操作起来很简单的压缩PPT方法
这几个方法轻松压缩ppt文件大小。在当今信息化迅速发展的时代,PPT已成为工作和学习中必不可少的工具。然而,随着内容的增加,文件体积常常变得庞大,影响了分享和传输的便利性。过大的文件不仅占用存储空间,还可能导致演…...

【nvm管理多版本node】下载安装以及常见问题和解决方案
nvm管理多版本node nvm 下载安装下载安装 nvm 常用命令其他常用命令 常见问题 nvm 下载安装 下载 nvm下载地址 每个版本下都有Assets,根据需要下载一个。 node下载地址 根据自己需要,可以下载可执行文件或者压缩包 安装 按提示安装即可。 安装过程中ÿ…...

C++(学习)2024.9.23
目录 运算符重载 1.概念 2.友元函数运算符重载 3.成员函数运算符重载 4.特殊运算符重载 1.赋值运算符重载 2.类型转换运算符重载 5.注意事项 std::string字符串类: 模板与容器 模板 1.函数模板 2.类模板 类内实现 类内声明类外实现 运算符重载 1.概念…...

大数据处理从零开始————3.Hadoop伪分布式和分布式搭建
1.伪分布式搭建(不会用,了解就好不需要搭建) 这里接上一节。 1.1 伪分布式集群概述 伪分布式集群就是只有⼀个服务器节点的分布式集群。在这种模式中,我们也是只需要⼀台机器。 但与本地模式不同,伪分布式采⽤了分布式…...

跟着问题学12——GRU详解
1 GRU 1. 什么是GRU GRU(Gate Recurrent Unit)是循环神经网络(Recurrent Neural Network, RNN)的一种。和LSTM(Long-Short Term Memory)一样,也是为了解决长期记忆 和反向传播中的梯度等问题…...

内核是如何接收网络包的
1、数据如何从网卡到网络协议栈 1.1内核收包的过程 1、数据帧从外部网络到达网卡 2、网卡把数据帧从自己的缓存DMA(拷贝到)和内核共有的RingBuffer上 3、网卡发出硬中断通知CPU 4、CPU响应硬中断,简单处理后发出软中断 5、k’softirqd线程处理软中断,调…...

计算机毕业设计之:基于微信小程序的电费缴费系统(源码+文档+讲解)
博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…...

【leetcode】环形链表、最长公共前缀
题目:环形链表 解法一:哈希表 创建一个哈希表,遍历链表先判断哈希表中是否含有要放入哈希表中的节点,如果该节点已在哈希表中出现那么说明该链表是环形的;如果链表节点出现nullptr那么就退出循环,该链表是…...

C#开发记录如何建立虚拟串口,进行串口通信,以及通信模板
记录时间;2024年4月 记录如何开启虚拟串口以及进行基础串口通信。 建立虚拟串口 使用的软件是vspd,建立虚拟串口之后就可以将他们当成实际物理连接的两个串口进行通信。 之后使用我们之前给出的通信模板,建立一个稍微规矩一点的界面。 界面建立 其中…...

电源设计的艺术:从底层逻辑到工程实践
在电子工程的世界里,电源设计是核心中的核心。它不仅是电子设备的能量源泉,更是整个系统稳定运行的基石。随着科技的不断进步,电源设计的要求也越来越高,从效率、稳定性到体积、成本,每一个维度都是工程师们不断追求的…...

软媒市场新探索:软文媒体自助发布,开启自助发稿新篇章
在繁华喧嚣的软媒市场中,每一个声音都在竭力呼喊,每一个品牌都在奋力展现。而软文,作为一种温柔而坚韧的营销力量,正逐渐崭露头角。特别是软文媒体自助发布平台的出现,更是为企业提供了一个全新的、高效的自助发稿渠道。 软媒市场自助发布平台,正如其名,是一个让企业能够自主发…...

【Kubernetes】常见面试题汇总(二十七)
目录 77.假设公司希望在不同的云基础架构上运行各种工作负载,从裸机到公共云。公司将如何在不同界面的存在下实现这一目标? 78.什么是 Google 容器引擎? 特别说明: 题目 1-68 属于【Kubernetes】的常规概念题。 题目 69-1…...

基于单片机巡迹避障智能小车系统
文章目录 前言资料获取设计介绍设计程序具体实现截图设计获取 前言 💗博主介绍:✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们…...

Python163邮箱发送:提升发送效率的技巧?
python163邮箱发送邮件教程?python怎么使用163邮箱? Python163邮箱发送作为一种自动化邮件发送方式,越来越受到开发者和企业的青睐。AokSend将探讨如何通过多种技巧提升Python163邮箱发送的效率,从而更好地满足用户需求。 Pytho…...

springboot中的异步任务
在springboot项目中可以通过EnableAsyncAsync的方式简化异步操作,下文使用springboot:3.2.1 源码分析 若一个bean中的公共方法上标注了Async,在系统启动时,会给这个类创建一个代理对象,并将该代理对象作为bean注册到spring容器中 …...

Linux学习笔记8 理解Ubuntu网络管理,做自己网络的主人
本文讲解了Ubuntu下网络由什么管理,介绍了临时ip和路由的设置方法,介绍了静态持久化网络配置的方法以及各网络管理软件之间的关系。 来看看Ubuntu网络管理。 序言 原本学习ubuntu网络管理就是为了检查nginx安装过程中使用wget获取压缩包为什么解析不出…...