C

C 知识量:16 - 74 - 317

11.4 字符串函数><

strlen()函数- 11.4.1 -

C语言有许多用于处理字符串的函数,例如:strlen()、strcat()、strcmp()、strncmp()、strcpy()和strncpy()函数等,它们的函数原型被放入了string.h头文件中,使用时程序应包含该头文件。

strlen()函数用于统计字符串的长度,不包含末尾的空字符。下面是一个使用strlen()函数的示例:

#include <stdio.h>
#include <string.h>

void fit(char *, int);

int main(void) {
    char message[] = "Hello pnotes.cn,I am Jeff and I like programming.";
    puts(message);
    fit(message, 10);
    printf("After fit: ");
    puts(message);
    printf("message + 9: ");
    puts(message + 9);
    printf("message + 10: ");
    puts(message + 10);
    printf("message + 11: ");
    puts(message + 11);
    system("pause");
    return 0;
} 

void fit(char *s, int limit) {
    if (strlen(s) > limit)
        s[limit] = '\0';
}

运行结果为:

Hello pnotes.cn,I am Jeff and I like programming.
After fit: Hello pnot
message + 9: t
message + 10:
message + 11: s.cn,I am Jeff and I like programming.

函数fit()中,通过strlen()获取了字符串s的长度,并与limit进行比较,如果s的长度大于limit,就将s[limit]的值修改为空字符,因此,s[10]被修改为'\0',从打印的结果也能看出这一点。

strcat()函数- 11.4.2 -

strcat()是用于拼接字符串的函数,它接受两个字符串作为参数。strcat()函数将第2个字符串的副本附加在第1个字符串的末尾,并把拼接后的新字符串作为第1个字符串,而第2个字符串不变(因为仅使用了它的副本)。

strcat()函数的类型是char *,它将返回拼接后的第1个字符串。以下是一个使用strcat()函数的示例:

#include <stdio.h>
#include <string.h>

int main(void) {
    char s1[50] = "Hello pnotes.cn,";
    char s2[] = "I am Jeff and I like programming.";
    printf("s1: %s\ns2: %s\n", s1, s2);
    strcat(s1, s2);
    printf("After strcat\ns1: %s\ns2: %s\n", s1, s2);
    system("pause");
    return 0;
}

运行结果为:

s1: Hello pnotes.cn,
s2: I am Jeff and I like programming.
After strcat
s1: Hello pnotes.cn,I am Jeff and I like programming.
s2: I am Jeff and I like programming.

strncat()函数- 11.4.3 -

strncat()函数的功能与strcat()函数一样,但是strncat()函数拥有第3个参数,用于限制拼接的字符串长度,以防止拼接导致储存第1个字符串的空间溢出。

如果使用strcat()函数,同时防止空间溢出,就需要对字符串长度进行判断和控制,例如下面的示例:

#include <stdio.h>
#include <string.h>

int main(void) {
    char s1[50] = "Hello pnotes.cn,";
    char s2[] = "I am Jeff and I like programming.";
    char s3[] = "Goodbye!";
    printf("s1: %s\ns2: %s\ns3: %s\n", s1, s2, s3);
    printf("Size of s1: %u\nSize of s2: %u\nSize of s3: %u\n",
            strlen(s1), strlen(s2), strlen(s3));
    if (strlen(s2) < 50 - strlen(s1)) {
        strcat(s1, s2);
    }
    printf("After first strcat\ns1: %s\n", s1);
    if (strlen(s3) < 50 - strlen(s1)) {
        strcat(s1, s3);
    }
    printf("After first strcat\ns1: %s\n", s1);
    printf("Size of s1: %u\nSize of s2: %u\nSize of s3: %u\n",
            strlen(s1), strlen(s2), strlen(s3));
    system("pause");
    return 0;
}

运行结果为:

s1: Hello pnotes.cn,
s2: I am Jeff and I like programming.
s3: Goodbye!
Size of s1: 16
Size of s2: 33
Size of s3: 8
After first strcat
s1: Hello pnotes.cn,I am Jeff and I like programming.
After first strcat
s1: Hello pnotes.cn,I am Jeff and I like programming.
Size of s1: 49
Size of s2: 33
Size of s3: 8

在以上代码中,进行了两次拼接尝试,第1次是将s1与s2拼接,第2次是将s1与s3拼接。通过利用strlen()函数对字符串长度进行判断和控制,实现了安全拼接。

如果利用strncat()函数,就不用这么麻烦,示例修改为:

#include <stdio.h>
#include <string.h>

int main(void) {
    char s1[50] = "Hello pnotes.cn,";
    char s2[] = "I am Jeff and I like programming.";
    char s3[] = "Goodbye!";
    printf("s1: %s\ns2: %s\ns3: %s\n", s1, s2, s3);
    printf("Size of s1: %u\nSize of s2: %u\nSize of s3: %u\n",
            strlen(s1), strlen(s2), strlen(s3));
    strncat(s1, s2, 50 - strlen(s1) - 1);
    printf("After first strcat\ns1: %s\n", s1);
    strncat(s1, s3, 50 - strlen(s1) - 1);
    printf("After second strcat\ns1: %s\n", s1);
    printf("Size of s1: %u\nSize of s2: %u\nSize of s3: %u\n",
            strlen(s1), strlen(s2), strlen(s3));
    system("pause");
    return 0;
}

运行结果为:

s1: Hello pnotes.cn,
s2: I am Jeff and I like programming.
s3: Goodbye!
Size of s1: 16
Size of s2: 33
Size of s3: 8
After first strcat
s1: Hello pnotes.cn,I am Jeff and I like programming.
After second strcat
s1: Hello pnotes.cn,I am Jeff and I like programming.
Size of s1: 49
Size of s2: 33
Size of s3: 8

需要注意的是strncat()的第3个参数表示:在将第2个字符串拼接到第1个字符串时,当加到第3个参数表示的数量时或遇到空字符时停止。而存储字符串的数组需要一个存储空字符'\0'的空间,因此,在设定第3个参数时应当考虑到这一点。例如以上示例中,当s1的长度变为49时,就表示存储s1的空间已满,而在设定strncat()的第3个参数时多减了一个1。

strcmp()函数- 11.4.4 -

strcmp()函数用于字符串的比较,以两个字符串作为参数,如果两个字符串参数相同,该函数就返回0,否则返回非0值。具体规定是:

  • 在字母表中,如果第1个字符串在第2个字符串前面,就返回一个负数。

  • 如果两个字符串相同,就返回0。

  • 如果第1个字符串在第2个字符串后面,就返回一个正数。

  • 返回的具体值取决于编译器的实现。

  • strcmp()会依次比较字符串的每一个字符,直到发现第1个不同的字符为止。

示例:

#include <stdio.h>
#include <string.h>

int main(void) {
    char s1[] = "B";
    char s2[] = "A";
    char s3[] = "B";
    char s4[] = "C";
    printf("s1: %s\ns2: %s\ns3: %s\ns4: %s\n", s1, s2, s3, s4);
    printf("s1:s2=%d\ns1:s3=%d\ns1:s4=%d\n",
            strcmp(s1, s2), strcmp(s1, s3), strcmp(s1, s4));
    system("pause");
    return 0;
}

运行结果为:

s1: B
s2: A
s3: B
s4: C
s1:s2=1
s1:s3=0
s1:s4=-1

strncmp()函数- 11.4.5 -

strncmp()函数功能与strcmp()函数相似,但是strncmp()函数在比较字符串时,可以比较到字符不同的地方,也可以只比较到第3个参数指定的字符数。示例如下:

#include <stdio.h>
#include <string.h>

int main(void) {
    char s1[] = "Ball";
    char s2[] = "Base";
    printf("s1: %s\ns2: %s\n", s1, s2);
    printf("use strcmp():\ns1:s2=%d\nuse strncmp():\ns1:s2=%d\n",
            strcmp(s1, s2), strncmp(s1, s2, 2));
    system("pause");
    return 0;
}

运行结果为:

s1: Ball
s2: Base
use strcmp():
s1:s2=-1
use strncmp():
s1:s2=0

如上所示,如果使用strncmp()只比较前两个字符的话,s1与s2是相同的。

strcpy()函数- 11.4.6 -

strcpy()函数是字符串拷贝函数,它拷贝的是字符串本身,而不是地址。

strcpy()函数有两个字符串指针类型的参数:

  • 第1个是目标字符串。

  • 第2个是源字符串。

  • strcpy()返回类型是char *,即第1个目标字符串的地址。

  • 第1个参数应当指向一个数据对象(例如数组),且该对象应当有足够的空间存储源字符串的副本。

  • 第2个参数可以声明为指针、数组名或字符串常量。

  • 第1个参数不必总是指向目标字符串(数组)的开始,也可以从目标字符串(数组)的其他位置开始拷贝。

以下是一个示例:

#include <stdio.h>
#include <string.h>

int main(void) {
    char s1[50] = "Base";
    char s2[] = "ball";
    printf("s1: %s\ns2: %s\n", s1, s2);
    printf("use strcpy():\n");
    strcpy(s1 + 4, s2);
    printf("s1: %s\ns2: %s\n", s1, s2);
    system("pause");
    return 0;
}

运行结果为:

s1: Base
s2: ball
use strcpy():
s1: Baseball
s2: ball

strncpy()函数- 11.4.7 -

strncpy()函数功能与strcpy()类似,但strncpy()的第3个参数可以控制可拷贝的最大字符数。

需要注意的是:如果拷贝到指定的最大字符数时,仍然没有拷贝完,拷贝将立刻结束,其中空字符也不会被拷贝,目标字符串中可能会缺少用于表示字符串结束的空字符(\0)。为防止此类情况,应当总是在拷贝结束后,将目标字符串的最后一位设为空字符。

sprintf()函数- 11.4.8 -

sprintf()函数声明在stdio.h中,它与printf()函数类似,但它是把数据写入到字符串中,而不是打印到显示器上。

可以利用sprintf()函数将多个元素组合成一个字符串,其中,第1个参数是目标字符串的地址,其他参数和printf()的相同。

示例:

#include <stdio.h>

int main(void) {
    char s1[50];
    char s2[] = "baseball";
    char *s3 = "and";
    int number = 5;
    char s4[] = "football";
    sprintf(s1, "%s %s %d %s", s2, s3, number, s4);
    printf("%s\n", s1);
    system("pause");
    return 0;
}

运行结果:

baseball and 5 football

其他字符串函数- 11.4.9 -

其他常用的字符串函数简介:

1、char *strchr(const char * s, int c);

如果s字符串中包含c字符,就返回指向s字符串中c出现的首位置的指针(末尾的空字符也在查找范围);如果未找到,就返回空指针。

2、char *strpbrk(const char * s1, const char * s2); 

如果s1字符串包含s2字符串中的任意字符,就返回指向s1字符串中s2任意字符出现的首位置的指针;如果未找到,就返回空指针。

3、char *strrchr(const char * s, int c);

该函数返回s字符串中c字符的最后一次出现的位置(末尾的空字符也在查找范围)。如果未找到,就返回空指针。

4、char *strstr(const char * s1, const char * s2);

该函数返回指向s1字符串中s2字符串出现的首位置。如果未找到,就返回空指针。