C语言的字符串函数。
目录
在C语言中,有一些常用的字符串库函数可用于处理字符串。
一、求字符串长度
-
strlen
size_t strlen ( const char * str );
参数 str
是一个指向以 null 结尾的字符串的指针。函数返回一个无符号整数 size_t
,表示字符串的长度。
strlen
的工作原理是在遇到第一个终止符 '\0' 之前,依次计算字符串中的字符个数,直到遇到终止符为止。
使用时需要注意确保传入的字符串是以 null 结尾的,否则可能导致未定义的行为。
size_t my_strlen1(const char *str) {
size_t count = 0;
while (*str != '\0') {
count++;
str++;
}
return count;
}
size_t my_strlen2(const char* str) {
if (*str == '\0')
return 0;
else
return 1 + my_strlen2(++str);
}
size_t my_strlen3(const char* str) {
const char* ptr = str;
while (*ptr != '\0') {
ptr++;
}
return ptr - str;
}
字符串函数可以根据操作的字符串长度是否受限制来进行分类。
二、长度不受限制的字符串函数
长度不受限制的字符串函数:这类函数在处理字符串时,没有明确的长度限制,会根据输入字符串的实际长度进行操作。常见的长度不受限制的字符串函数有:
-
strcpy
char * strcpy ( char * dest, const char * src );
strcpy
函数将源字符串 src
中的内容复制到目标字符串 dest
中,并返回指向目标字符串 dest
的指针。需要注意的是,目标字符串 dest
必须具有足够的空间来容纳源字符串 src
的内容,以确保复制的安全性。
需要注意的是,为了确保目标字符串不会溢出,你应该确保目标字符串有足够的容量来存储源字符串的内容,包括结尾的空字符 '\0'。否则,可能会导致缓冲区溢出的问题。
char* my_strcpy(char* destination, const char* source) {
char* ret = destination;
assert(destination != NULL);
assert(source != NULL);
while (*source != '\0') { // 循环直到源字符串结束
*destination = *source; // 将源字符串的字符复制到目标字符串
destination++; // 移动目标字符串指针
source++; // 移动源字符串指针
}
*destination = '\0';
return ret;
}
-
strcat
char * strcat ( char * destination, const char * source );
strcat是一个用于字符串拼接的函数,可以将一个字符串追加到另一个字符串的末尾。
source源字符串必须以 '\0' 结束。 目标空间必须有足够的大,能容纳下源字符串的内容。 且目标空间必须可修改。
char* my_strcat(char* destination, const char* source) {
assert(destination);
assert(source);
char* ret = destination;
while (*destination ) {
destination++;
}
strcpy(destination, source);
//while (*destination++ = *source++);
return ret;
}
其中,dest
为目标字符串,src
为要追加的源字符串。该函数会将源字符串的内容追加到目标字符串的末尾,并返回指向目标字符串的指针。
需要注意的是,dest
数组需要足够大,以容纳目标字符串和源字符串的拼接结果。否则,可能导致缓冲区溢出等问题。
-
strcmp
int strcmp ( const char * str1, const char * str2 );
该函数接受两个参数:str1
和str2
,分别表示要比较的两个字符串。它会逐个比较两个字符串中对应位置的字符,直到遇到不同的字符或者字符串结束符('\0')。如果两个字符串完全相同,则返回值为0;如果第一个不同的字符在str1
中的ASCII码小于在str2
中的ASCII码,则返回值为负数;如果第一个不同的字符在str1
中的ASCII码大于在str2
中的ASCII码,则返回值为正数。
int my_strcmp(const char* str1, const char* str2){
assert(str1);
assert(str2);
while (*str1 == *str2) {
if (*str1 == '\0')return 0;
str1++;
str2++;
}
return (*str1 - *str2 ) >0 ?1:-1;
}
三、长度受限制的字符串函数
长度受限制的字符串函数:这类函数对输入字符串的长度有一定的限制,需要指定处理的字符个数或最大允许的字符个数。常见的长度受限制的字符串函数有:
-
strncpy
:将源字符串 src 中的前 n 个字符复制到目标字符串 dest。如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。
char * strncpy ( char * destination, const char * source, size_t num );
-
strncat
:将源字符串 src 中的前 n 个字符追加到目标字符串 dest 的末尾。
char * strncat ( char * destination, const char * source, size_t num );
-
strncmp
:比较两个字符串 str1 和 str2 的前 n 个字符是否相等。
int strncmp ( const char * str1, const char * str2, size_t num );
四、字符串查找
-
strstr
const char * strstr ( const char * str1, const char * str2 );
char * strstr ( char * str1, const char * str2 );
其中,str1是要进行查找的字符串,str2是要查找的目标字符串。
该函数会在str1中查找第一次出现str2的位置,并返回指向该位置的指针。如果找不到则返回NULL。它可以用来判断一个字符串是否包含另一个字符串。
char* my_strstr(char* str1, const char* str2) {
assert(str1);
if (*str2 == '\0')return str1;
char* cp = str1;
char* s1 = cp;
char* s2 = str2;
while (*cp != '\0')
{
s1 = cp;
s2 = str2;
while (*s1 != '\0' && s2 != '\0' && *s1 == *s2)
s1++, s2++;
if (*s2 == '\0')
return cp;
cp++;
}
return NULL;
}
- strtok
char * strtok ( char * str, const char * delimiters );
它接受两个参数:要分割的字符串和分割字符集合。函数会从字符串中找到第一个与分割字符集合中的任何字符匹配的字符,并将该字符替换为字符串结束符\0
。然后,函数返回指向原始字符串中的第一个非空字符的指针,即分割后的第一个标记。如果没有找到分割字符,则函数返回NULL
。
下一次调用strtok
时,应将第一个参数设置为NULL
,此时函数将继续在上一次调用结束的位置继续查找,并返回下一个标记的指针。这样,可以通过连续调用strtok
来逐个获取字符串中的所有标记。
五、错误信息报告
strerror
char * strerror ( int errnum );
strerror是一个函数,它用于返回与指定错误代码对应的错误消息字符串。在C语言中,我们可以使用该函数来获取由系统函数返回的错误代码所对应的错误描述。
例如,如果我们调用了一个系统函数并得到了一个错误码,我们可以使用strerror函数将其转换为可读的错误消息。具体的使用方法如下:
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main() {
FILE *file = fopen("nonexistent.txt", "r");
if (file == NULL) {
int error_code = errno;
const char *error_msg = strerror(error_code);
printf("Error opening file: %s", error_msg);
}
return 0;
}
在上述示例中,我们通过fopen函数试图打开一个不存在的文件。如果打开失败,我们使用errno变量获取错误码,然后使用strerror函数将错误码转换为对应的错误消息字符串,并打印出来。
需要注意的是,strerror函数采用的是当前线程的全局错误码,因此在多线程环境中需要谨慎使用。此外,错误码和错误消息的具体取值可能因操作系统而异,可以参考相关文档以了解特定平台上的实现细节。
六、字符操作
在 C 语言中,通过 <ctype.h>
头文件提供的字符分类函数库可以对字符进行分类。下面列举了一些常用的字符分类函数:
isalpha():用于判断字符是否为字母(包括大写和小写字母)。
isdigit():用于判断字符是否为数字(0-9)。
isalnum():用于判断字符是否为字母或数字。
isspace():用于判断字符是否为空白字符,如空格、制表符、换行符等。
ispunct():用于判断字符是否为标点符号。
isupper():用于判断字符是否为大写字母。
islower():用于判断字符是否为小写字母。
tolower():用于将字符转换为小写字母。
toupper():用于将字符转换为大写字母。
这些函数都接受一个 int
类型的参数,参数应为 unsigned char
或 EOF
的值或者是 EOF
宏。函数的返回值为非零表示字符满足相应的条件,返回值为零表示字符不满足条件。