把知识记在小本本上

将零散的知识点放在一个集中的地方,不断递归重构,形成一套为己所用的知识系统。

博客首页 | 小本本首页

字符串函数

#include <string.h>

strlen()

size_t strlen(const char *s);

  • \0作为结束标志,这个函数返回的是字符串中第一个\0前面的字符个数,不包括\0
  • 函数的返回值是size_t,是一个无符号的数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <string.h>

int main(int argc, const char * argv[])
{
const char * s1 = "abcdef";
const char * s2 = "ab";
if(strlen(s2) - strlen(s1) > 0) // 无符号数 - 无符号数 = 无符号数
{
printf("s1 < s2\n"); // 输出这句!
}
else
{
printf("s1 > s2\n");
}

return 0;
}

strcpy()

char * stpcpy(char * dst, const char * src);

  • 函数的返回值是拷贝后的dst的地址。

  • 源字符串必须以\0结束。

  • 会将源字符串中的\0拷贝到目标空间。

  • 目标空间必须足够大,足以容纳源字符串。

  • 目标空间必须可以改变!

    strncpy()

    char * strncpy(char * dst, const char * src, size_t len);

    • 拷贝len个字符串从源字符串到目标字符串
    • 如果源字符串的长度小于len,拷贝完源字符串之后,在目标后面继续追加0,直到len个。

    strncpy

strcat()

char * strcat(char *restrict s1, const char *restrict s2);

  • 源字符串必须以\0结束。

  • 目标空间必须足够大,足以容纳源字符串。

  • 目标空间必须可以改变!

  • 字符串自己给自己拼接,会把\0覆盖掉(因为拼接过程是一个字符一个字符的copy)。

    strncat()

    char * strncat(char *restrict s1, const char *restrict s2, size_t n);

    • 从s2中拷贝n个字符串到s1字符串的后面,如果s2字符串的长度小于n,只拷贝到\0为止。

    strncat

strcmp()

int strcmp(const char *s1, const char *s2);

注意!这个函数比较的是对应位置的ascii码的大小,而不是比较长度。

  • s1 > s2,返回大于0的数。

  • s1 == s2,返回0。

  • s1 < s2,返回小于0的数。

    strncmp()

    int strncmp(const char *s1, const char *s2, size_t n);

    • 比较到出现第一个字符不一样的地方或一个字符串结束或者n个字符全部比完。

    栗子:查找以R2开头的字符串。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    int main()
    {
    char str[][5] = { "R2D2", "C3PO", "R2A6" };
    for(int n=0; n<3; n++)
    {
    if(strncmp(str[n], "R2xx", 2) == 0)
    {
    printf("%s\n", str[n]);
    }
    }

    return 0;
    }

strstr()

char * strstr(const char *haystack, const char *needle);

  • 查找第二个字符串参数在第一个参数重首次出现的地方,返回指向这个地方的指针。

栗子:

1
2
3
4
5
6
7
8
9
10
11
int main()
{
char str[] = "This is a simple string!";
char * p = NULL;
p = strstr(str, "simple");
printf("%s\n", p);
strncpy(p, "aaaaaa", 6);
puts(p);

return 0;
}

strtok()

char * strtok(char *restrict str, const char *restrict sep);

打散字符串!

  • 第一个参数str是要打散的字符串,第二个参数是个字符串,定义了用作分隔符的字符集合。

  • 第一个参数必须是可以修改的。打散的过程其实就是将str中出现sep的地方替换为\0,对于str中连续出现的分隔符,只会将第一个分隔符替换为\0,其他的跳过。

    例如:str = str:::str:end,sep = :

  • strtok函数的第一个参数不为NULL,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。

  • strtok函数的第一个参数为NULL,函数将在同一个字符串中被保存的位置开始,查找下一个标记。

  • 如果字符串中不存在更多的标记,返回NULL指针。

栗子1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <string.h>

int main()
{
char str[100] = "abcdefg@qq.com";
char *e = "@.";
char *p = NULL;
p = strtok(str, e);

while(p != NULL)
{
puts(p);
p = strtok(NULL, e);
}

return 0;
}

栗子2:

1
2
3
4
5
6
7
8
9
10
11
12
13
int main()
{
char str[100] = "str::::str...end";
char *e = ":.";
char *p = strtok(str, e);
while(p != NULL)
{
puts(p);
p = strtok(NULL, e);
}

return 0;
}

strtok

可以看到,当出现连续的分隔符时候,只会把第一个分隔符替换为\0,跳过后面的分隔符,返回的值是遇到的第一个不是分隔符的地址。

strerror()

char * strerror(int errnum);

  • 返回错误码,对应的错误信息。

栗子:输出结果:No such file or directory

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
#include <string.h>
#include <errno.h>

int main()
{
FILE *fp = fopen("test.txt", "r");
if(fp == NULL)
{
printf("%s\n", strerror(errno));
}

return 0;
}

在C库中,errno.h是一个全局的错误码,成功为0,不成功为非0。非0表示失败,还有为什么失败的字符串描述。

main函数的返回值称为程序的退出码,在Linux下使用:echo $?命令可以查看最近一次程序执行完成的退出码。

echo $?

字符函数

#include <ctype.h>

函数 参数满足以下条件,返回值为1
iscntrl() 任何控制字符
isspace() 空白字符:空格、换页符、换行、回车、制表符\t或者垂直制表符\v
isdigit() 十进制数字:0~9
isxdigit() 十六进制数字:0~9、A~F、a~f
islower() 是小写字母
isupper() 是大写字母
isalpha() 是字母a~z、A~Z
isalnum() 是字母或者十进制数字
ispunct() 标点符号,任何不属于数字或字母的图形字符(可打印)
isgraph() 任何图形字符
isprint() 任何可打印的字符