字符串基础
字符串的常见函数:
strlen() // 计算字符串的长度,即字符串中字符的个数(不包括字符串末尾的空字符'\0' strcpy() // 将一个字符串复制到另一个字符串中。目标字符串必须有足够的空间来容纳被复制的字符串。 strcat() // 将一个字符串追加到另一个字符串的末尾。目标字符串必须有足够的空间来容纳追加后的字符串。 strcmp() // 比较两个字符串是否相等。如果相等,返回0;如果第一个字符串小于第二个字符串,返回负值;如果第一个字符串大于第二个字符串,返回正值。
字符串的几个限定字符个数的函数:
int strncmp(const char *str1, const char *str2, size_t n) // 函数与返回值说明 功能:比较两个字符串的前n个字符是否相等。 返回值:如果字符串相等,返回0;如果str1小于str2,返回小于0的值;如果str1大于str2,返回大于0的值。 char *strncpy(char *dest, const char *src, size_t n) // 函数与返回值说明 功能:将源字符串的前n个字符复制到目标字符串中。如果源字符串长度小于n,则在目标字符串中以空字符'\0'填充剩余空间。 返回值:返回指向目标字符串的指针。
常见字符串函数的使用demo:
strlen使用demo:
#include <stdio.h> #include <string.h> int main() { char * str1 = "Hello"; // char str2[] = {'H', 'e', 'l', 'l', 'o', '\0'}; char str2[] = {'H', 'e', 'l', 'l', 'o'}; printf("strlen(str1) = %d \n", strlen(str1)); // 正常使用,大小为5,不包括'\0' printf("strlen(str2) = %d \n", strlen(str2)); // 此处大小为5 printf("sizeof(str1) = %d \n", sizeof(str1)); // 打印的是指针所占的字节数,与编译器有关 printf("sizeof(str2) = %d \n", sizeof(str2)); // 打印的是str2占用空间的大小,此处为5 printf("str1 = %s\n", str1); // 正常打印Hello printf("str2 = %s\n", str2); // 打印会出现异常,因为没有'\0'判断字符串的结束 }
strcpy使用demo:
#include <string.h> #include <stdio.h> int main() { char src[] = "Hello"; char dest[20]; strcpy(dest, src); printf("Copied string: %s\n", dest); return 0; }
strcat使用demo:
#include <string.h> #include <stdio.h> int main() { char str1[20] = "Hello"; char str2[] = " World!"; strcat(str1, str2); printf("Concatenated string: %s\n", str1); return 0; }
strcmp使用demo:
#include <string.h> #include <stdio.h> int main() { char str1[] = "Hello"; char str2[] = "Hello"; int result = strcmp(str1, str2); if (result == 0) { printf("Strings are equal\n"); } else { printf("Strings are not equal\n"); } return 0; }
strncpy使用demo:
#include <stdio.h> #include <string.h> int main() { char src[] = "Hello"; char dest[10]; strncpy(dest, src, sizeof(dest) - 1); // 正确的使用,确保目标字符串以空字符结尾 dest[sizeof(dest) - 1] = '\0'; // 手动添加结尾的空字符 // 打印目标字符串 printf("Copied string: %s\n", dest); return 0; }
strncmp使用demo:
#include <stdio.h> #include <string.h> int main() { char str1[] = "Hello"; char str2[] = "World"; // 比较前 3 个字符 int result1 = strncmp(str1, str2, 3); if (result1 == 0) { printf("The first 3 characters of str1 and str2 are equal.\n"); } else if (result1 < 0) { printf("The first 3 characters of str1 are less than str2.\n"); } else { printf("The first 3 characters of str1 are greater than str2.\n"); } // 比较整个字符串 int result2 = strncmp(str1, str2, strlen(str2)); if (result2 == 0) { printf("str1 and str2 are equal.\n"); } else if (result2 < 0) { printf("str1 is less than str2.\n"); } else { printf("str1 is greater than str2.\n"); } return 0; }
常见字符串处理问题:
1、缓冲区溢出
#include <stdio.h> #include <string.h> int main() { char buffer[5]; // 缓冲区大小为5 char source[] = "Hello, World!"; // 长度为13 // 使用 strcpy 函数将 source 复制到 buffer 中 strcpy(buffer, source); // 缓冲区溢出,source 长度大于 buffer 大小 printf("Buffer: %s\n", buffer); // 输出 buffer return 0; }
2、字符串拼接错误
#include <stdio.h> #include <string.h> int main() { char buffer[12] = "Hello"; // 缓冲区大小为12 char suffix[] = ", World!"; // 长度为9 // 使用 strcat 函数将 suffix 拼接到 buffer 后面 strcat(buffer, suffix); // 缓冲区溢出,拼接后的字符串长度大于 buffer 大小 printf("Buffer: %s\n", buffer); // 输出 buffer return 0; }
3、未终止的字符串
#include <stdio.h> int main() { char str[5] = {'H', 'e', 'l', 'l', 'o'}; // 未包含终止符 \0 printf("String: %s\n", str); // 输出未终止的字符串,可能导致输出不受控制 return 0; }
4、内存泄漏
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char *str = (char *)malloc(6 * sizeof(char)); // 分配内存 if (str == NULL) { printf("Memory allocation failed!\n"); return 1; } strcpy(str, "Hello"); // 复制字符串到动态分配的内存 // 在程序结束前忘记释放内存 // free(str); printf("String: %s\n", str); // 输出字符串 return 0; }
常见字符串函数的实现:
strcpy实现:
#include <stdio.h> #include <string.h> void my_strcpy(char *des, char *src) { while(*src != '\0') { *des = *src; src++; des++; } *des = '\0'; } int main() { char str1[] = {'H', 'e', 'l', 'l', 'o', '\0'}; char str2[6]; my_strcpy(str2, str1); printf("str1 = %s, str2 = %s\n", str1, str2); return 0; }
strcat实现:
#include <stdio.h> #include <string.h> void my_strcat(char *dst, char *sou) { while(*dst != '\0') { dst++; } while(*sou != '\0') { *dst = *sou; dst++; sou++; } *dst = '\0'; } int main() { char s1[20] = "Hello"; char s2[] = "world"; my_strcat(s1, s2); printf("s1 = %s\n", s1); }
strcmp实现:
#include <stdio.h> #include <string.h> int my_strcmp(char *str1, char *str2) { while (*str1 != '\0' && *str2 != '\0') { if (*str1 > *str2) { return 1; } else if (*str1 < *str2) { return -1; } else { } str1 ++; str2 ++; } return 0; } int main() { char *str1 = "Hello world"; char *str2 = "Hello World"; int ret; ret = my_strcmp(str1, str2); printf("ret = %d \n", ret); printf("str1 = %s, str2 = %s\n", str1, str2); return 0; }
strncmp实现:
#include <stdio.h> #include <string.h> int my_strncmp(char *str1, char *str2, int num) { if (num <= 0) return 0; int tmp_num = 0; while(*str1 != '\0' && *str2 != '\0' && tmp_num < num) { if (*str1 > *str2) { return 1; } else if (*str1 < *str2) { return -1; } else { } str1 ++; str2 ++; tmp_num ++; } if (tmp_num == num || (*str1 == '\0' && *str2 == '\0')) return 0; return (*str1 == '\0') ? -1 : 1; } int main() { char *str1 = "hello"; char *str2 = "hello"; int ret = 0; ret = my_strncmp(str1, str2, 3); printf("ret = %d\n", ret); }