【c语言】字符函数和字符串函数

长度不受限制的字符串函数:

一、strlen

size_t strlen ( const char * str );

参数一为字符串;返回值为无符号整型。

1.功能:获取字符串长度

获取目标字符串(str)的长度,即元素个数,并返回。

#include <stdio.h>
#include <string.h>
int main()
{
    printf("%d\n", strlen("abcdefg"));
    return 0;
}

2.注意

①字符串已经 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包

含 '\0' )。

#include <stdio.h>
#include <string.h>
int main()
{
    printf("%d\n", strlen("ab\0cdefg"));
    return 0;
}

②参数指向的字符串必须要以 '\0' 结束,否则会继续向后查找

int main()
{
    char arr[] = { 'a','b','c','d' };
    printf("%d\n", strlen(arr));
    return 0;
}

③注意函数的返回值为size_t,是无符号的

int main()
{
    if (strlen("abcd") - strlen("abcdef") > 0)
    {
        printf("结果大于0\n");
    }
    return 0;
}

3.模拟实现

#include <stdio.h>
#include <string.h>
size_t my_strlen(const char* arr)
{
    int a = 0;
    while (*arr++)
    {
        a++;
    }
    return a;
}
int main()
{
    char arr[] = "abcdef";
    printf("%u\n", my_strlen(arr));
    return 0;
}
#include <stdio.h>
size_t my_strlen(const char* arr)
{
    if (*arr != '\0')
        return 1 + my_strlen(arr + 1);
    else
        return 0;
}
int main()
{
    char arr[] = "abcefs";
    printf("%d\n", my_strlen(arr));
    return 0;
}

二、strcpy

char * strcpy ( char * destination, const char * source );

参数一为字符指针;参数二为字符指针;返回值为字符指针。

1.功能:拷贝字符串

将源(source)指向的 C 字符串复制到目标指向的数组(destination)中,包括终止的 \0 字符(并在该点停止),最终返回目标数组地址。

#include <stdio.h>
#include <string.h>
int main()
{
    char arr[10] = "abcd";
    char abb[] = "efg";
    printf("%s\n", strcpy(arr, abb));
    return 0;
}

2.注意

①源字符串必须以‘\0’结尾,因为strcpy遇\0停止拷贝,否则会继续向后拷贝

#include <stdio.h>
#include <string.h>
int main()
{
    char arr[] = {'a','b','c'};
    char abb[20] = "xxxxxxxx";
    printf("%s\n", strcpy(abb, arr));
    return 0;
}

②会将源字符串中的’\0‘拷贝到目标空间

#include <stdio.h>
#include <string.h>
int main()
{
    char arr[] = "abc\0ef";
    char add[10] = "xxxxxxxxx";
    printf("%s\n", strcpy(add, arr));
    return 0;
}

③目标空间必须足够大,以确保能存放源字符串

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

int main()
{
    char arr[] = "asdfwfgfa";
    char abb[3] = "xxx";
    printf("%s\n", strcpy(abb, arr));
    return 0;
}

④目标空间必须可变

#include <stdio.h>
#include <string.h>
int main()
{
    char* arr = "asdffwfgg";//指向常量字符串的指针
    char abb[] = "abcdefg";
    printf("%s\n", strcpy(abb, arr));
    return 0;
}

3.模拟实现

#include <stdio.h>
#include <string.h>
char* my_strcpy(char* add, const char* arr)
{
    char* a = add;
    while (*arr)
    {
        *add++ = *arr++;
    }
    return a;
}
int main()
{
    char arr[] = "abc\0ef";
    char add[10] = "xxxxxxxxx";
    printf("%s\n", strcpy(add, arr));
    return 0;
}

三、strcat

char * strcat ( char * destination, const char * source );

参数一为字符指针;参数二为字符指针;返回值为字符指针。

1.功能:追加字符串

将源字符串(source)的副本追加到目标字符串。目标字符串(destination)的终止的null(’\0‘)字符被源的第一个字符覆盖,并且包含一个空字符在新字符串的末尾

#include <stdio.h>
#include <string.h>
int main()
{
    char arr[20] = "abcdefg";
    char add[] = "abc";
    printf("%s\n", strcat(arr, add));
    return 0;
}

2.注意

①源字符串必须以 '\0' 结束,会不断向后追加

#include <stdio.h>
#include <string.h>
int main()
{
    char arr[20] = "abcdefg";
    char add[] = {'a','b','c','d'};
    printf("%s\n", strcat(arr, add));
    return 0;
}

②目标字符串要有'\0',从’\0‘开始追加。

#include <stdio.h>
#include <string.h>
int main()
{
    char arr[20] = "abcd \0xxxxx";
    char add[] = "hello";
    printf("%s\n", strcat(arr, add));
    return 0;
}

③目标空间必须有足够的大,能容纳下源字符串的内容

#include <stdio.h>
#include <string.h>
int main()
{
    char arr[10] = "abcdefgh";
    char add[] = "bagayalu";
    printf("%s\n", strcat(arr, add));
    return 0;
}

④目标空间必须可修改

#include <stdio.h>
#include <string.h>
int main()
{
    const char arr[10] = "abcdefgh";
    char add[] = "ba";
    printf("%s\n", strcat(arr, add));
    return 0;
}

⑤自己给自己追加,修改目标字符串的’\0‘,致使无法结束

#include <stdio.h>
#include <string.h>
int main()
{
    char arr[20] = "abcdefgh";
    printf("%s\n", strcat(arr, arr));
    return 0;
}

3.模拟实现

#include <Stdio.h>
#include <string.h>
char* my_strcat(char* arr, const char* add)
{
    char* ff = arr;
    while (*arr != '\0')
    {
        arr++;
    }
    while (*arr = *add)
    {
        add++;
        arr++;
    }
    return ff;
}
int main()
{
    char arr[20] = "halle ";
    char add[] = "word";
    printf("%s\n", my_strcat(arr, add));
    return 0;
}

四、strcmp

int strcmp ( const char * str1, const char * str2 );

参数为锁定的字符指针,返回值是整形。

1.功能:比较两个字符串

此函数开始比较每个字符串的第一个字符。如果它们彼此相等,则继续以下对,直到字符不同或达到终止空字符。此函数执行字符的二进制比较(比较字符的ascll码值)。

#include <stdio.h>
#include <string.h>
int main()
{
    char arr[10] = "abcdefg";
    char add[10] = "abcdefG";
    int a = strcmp(arr, add);
    if (a)
    {
        printf("arr > add\n");
    }
    else if (a = 0)
    {
        printf("相等\n");
    }
    else
    {
        printf("arr < add\n");
    }
    return 0;
}

2.模拟实现

#include <string.h>
#include <stdio.h>
int my_strcmp(const char* arr, const char* add)
{
    while (*arr == *add && *arr !='\0')
    {
        arr++;
        add++;
    }
    return *arr - *add;
 }
int main()
{
    char arr[10] = "abcdefg";
    char add[10] = "abcdefg";
    int a = my_strcmp(arr, add);
    if (a != 0)
        printf("不相等\n");
    else
        printf("相等\n");
    return 0;
}

长度受限制的字符串函数:

五、strncpy

char * strncpy ( char * destination, const char * source, size_t num );

参数一,指向要在其中复制内容的目标数组的指针;参数二,要复制的源字符串;要从复制的最大字符数,类型为无符号整型。

  1. 功能:从字符串中拷贝一定字符

从指针destination的位置起拷贝源字符串num个字符,如果在复制 num 个字符之前找到源字符串的末尾(‘\0’为标志),则目标将填充零,直到总共写入 num 个字符为止;

如果源长度超过 num,则不会在目标末尾隐式附加'\0'字符。因此,在这种情况下,不应将目标视为以'\0'结尾的字符串(这样读取它会溢出)。

#include <Stdio.h>
#include <String.h>
int main()
{
    char arr[10] = "abcdef";
    char add[] = "xxxx";
    printf("%s\n",strncpy(arr,add,2));
    return 0;
}
#include <Stdio.h>
#include <String.h>
int main()
{
    char arr[10] = "abcdef";
    char add[] = "xxxx";
    printf("%s\n",strncpy(arr,add,6));
    return 0;
}

六、strncat

char * strncat ( char * destination, const char * source, size_t num );

参数一,目标字符串地址;参数二,源字符串地址(锁定);参数三,要追加的最大字符数。

1.功能:从字符串追加一定字符

从目标字符串的末尾(‘\0’)将源的num个字符追加到目标,外加一个终止'\0'字符;

如果源中字符串的长度小于 num,则仅复制终止空字符之前的内容。

#include <Stdio.h>
#include <String.h>
int main()
{
    char arr[20] = "abcdef \0xxxx";
    char add[8] = "wwwwwww";
    printf("%s\n", strncat(arr, add, 3));
    return 0;
}
#include <Stdio.h>
#include <String.h>
int main()
{
    char arr[20] = "abcdef \0xxxx";
    char add[8] = "1234567";
    printf("%s\n", strncat(arr, add, 9));
    return 0;
}

七、strncmp

int strncmp ( const char * str1, const char * str2, size_t num );

参数一,要比较的字符串;参数二,要比较的字符串;要比较的最大字符数。

  1. 功能:比较两个字符串的字符

将 C 字符串 str1 的字符数与 C 字符串 str2 的字符进行比较。

此函数开始比较每个字符串的第一个字符。如果它们彼此相等,则继续使用向后依次对,直到字符不同,直到达到终止的空字符,或者直到两个字符串中的第 num 个字符匹配,以先发生者为准。

#include <Stdio.h>
#include <String.h>
int main()
{
    char arr[10] = "abcdefg";
    char add[] = "abc";
    printf("%d\n", strncmp(arr, add, 3));
    return 0;
}
#include <Stdio.h>
#include <String.h>
int main()
{
    char arr[10] = "abcdefg";
    char add[] = "abc";
    printf("%d\n", strncmp(arr, add, 4));
    return 0;
}
#include <Stdio.h>
#include <String.h>
int main()
{
    char arr[10] = "abcdefg";
    char add[] = "abcdefgh";
    printf("%d\n", strncmp(arr, add, 9));
    return 0;
}

八、strstr

char * strstr ( const char *str1, const char * str2);

参数一,要扫描的字符串;参数二,要查找的字符串;返回值,指向 str1 中指定的整个字符序列在 str2 中首次出现的指针,如果序列在 str1 中不存在,则为 null 指针。

1.功能:查找子字符串

返回指向 str2 中第一次出现的 str1 的指针,如果 str2 不是 str1 的一部分,则返回一个空指针。

匹配过程不包括终止空字符,但它到此为止。

#include <stdio.h>
#include <string.h>
int main()
{
    char arr[20] = "abcdef";
    char add[] = "cde";
    char* ff = strstr(arr, add);
    if (ff != NULL)
    {
        printf("找到了\n%s\n",ff);
    }
    else
        printf("没找到\n");
    return 0;
}

2.模拟实现

#include <Stdio.h>
#include <String.h>
char* my_strstr(const char* arr, const char* add)
{
    while (*arr)
    {
        char* aaa = (char*)arr;
        char* ddd = (char*)add;
        if (*aaa == *ddd)
        {
            while (*arr && *add && *aaa == *ddd)
            {
                aaa++;
                ddd++;
            }
            if (*ddd == '\0')
            {
                return arr;
            }
        }
        arr++;
    }
    return NULL;
}
int main()
{
    char arr[20] = "abcdefghigk";
    char add[] = "ghi";
    char* ff = my_strstr(arr, add);
    if (ff == NULL)
    {
        printf("没找到\n");
    }
    else
    {
        printf("找到了%s\n", ff);
    }
    return 0;
}

九、strtok

char * strtok ( char * str, const char * delimiters );

参数一,被分割字符串的指针;参数二,分隔符集合的指针;返回值,

1.功能:将字符串拆分为标记

  • 第一个参数指定一个字符串,它包含了0个或者多个由delimiters字符串中一个或者多个分隔符分割的标记。

  • delimiters参数是个字符串,定义了用作分隔符的字符集合。

  • strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)

  • strtok函数的第一个参数不为 NULL ,函数先将其作为str中第一个位置,返回这个位置的地址,同时strtok函数将保存找到的分割符在字符串中的下一个位置作为新的位置。

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

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

#include <stdio.h>
#include <string.h>
int main()
{
    char arr[30] = "huizuoshouxiezi@csdn.com";
    char p[] = "@.";
    char add[30] = { 0 };
    strcpy(add, arr);
    char* str = NULL;
    for (str = strtok(add, p); str != '\0'; str = strtok(NULL, p))
    {
        printf("%s", str);
    }
    return 0;
}

2.注意

①被分割字符串不必须为可修改的,非const修饰的

#include <stdio.h>
#include <string.h>
int main()
{
    const char* arr = "huizuoshouxiezi@csdn.com";
    const char p[] = "@.";
    char* str = NULL;
    for (str = strtok(arr, p); str != '\0'; str = strtok(NULL, p))
    {
        printf("%s", str);
    }
    return 0;
}

3.模拟实现

#include <stdio.h>
#include <string.h>
char* my_strtok(char* str, const char* add)
{
    static int b = 0;
    static char* aff = NULL;
    if (str != NULL)
    {
        aff = str;
        b = 0;
    }
    if (b == 1) return NULL;
    char* affb = aff;
    while (1)
    {
        if (*aff == '\0') b = 1;
        char* s = add;
        char* f = aff;
        while (1)
        {
            if (*f == *s)
            {
                *aff = '\0';
                aff += 1;
                return affb;
            }
            if (*s == '\0')
                break;
            s++;
        }
        aff++;
    }
}
int main()
{
    char arr[30] = "huizuoshouxiezi@csdn.com";
    char p[] = "@.";
    char* str = NULL;
    for (str = my_strtok(arr, p); str != '\0'; str = my_strtok(NULL, p))
    {
        printf("%s", str);
    }
    return 0;
}

十、strerror

char * strerror ( int errnum );

参数一,整形,错误号;返回值,指向描述错误错误的字符串的指针。

1.功能:获取指向错误消息字符串的指针

解释 errnum 的值,生成一个字符串,其中包含描述错误条件的消息,就像由库的函数设置为 errno 一样。

返回的指针指向静态分配的字符串,程序不应修改该字符串。对此函数的进一步调用可能会覆盖其内容(不需要特定的库实现来避免数据争用)

#include <stdio.h>
#include <string.h>
int main()
{
    char* arr = strerror(0);
    printf("%s\n", arr);
    arr = strerror(1);
    printf("%s\n", arr);
    arr = strerror(2);
    printf("%s\n", arr);
    arr = strerror(3);
    printf("%s\n", arr);
    return 0;
}

2.相关

①errno 错误码

从语言库函数在调用失败的时候,会将一个错误码存放在一个叫:errno的变量中,当我们想知道调用库函数的时候发生了什么错误信息,就可以通过strerror将errno中的错误码翻译成错误信息。

头文件:<errno.h>

注意:每次函数调用失败都会修改errbo的值,需要及时对errno使用。

②打开文件fopen

格式:FILE* 指针 = fopen("文件名","但开方式");

例:FILE* pf = fopen("test.txt","r");

(注:“r”为以读的方式打开)

返回值:

以FILE*指针接受;

文件打开失败会返回空指针NULL;(文件存在打开成功,文件不存在则打开失败)

③关闭文件fclose

格式:fclose(对应指针); 对应指针 = NULL;

例:fclose(pf); pf = NULL;

#include <string.h>
#include <stdio.h>
#include <errno.h>
int main()
{
    //打开文件
    FILE* pf = fopen("test.txt", "r");
    printf("%s\n", strerror(errno));
    //关闭文件
    fclose(pf);
    pf = NULL;
    return 0;
}

十一:perror

perror(char*);

参数一,输出内容;

1.功能:输出错误信息

类似:printf + strerror,打印内容和错误信息。

#include <string.h>
#include <stdio.h>
#include <errno.h>
int main()
{
    //打开文件
    FILE* pf = fopen("test.txt", "r");
    if (pf == NULL)
    {
        perror("文件打开失败:");
        return 0;
    }
    //关闭文件
    fclose(pf);
    pf = NULL;
    return 0;
}

十二.memcpy

void * memcpy ( void * destination, const void * source, size_t num );

  • 参数一,指向要在其中复制内容的目标数组的指针,类型转换为 void* 类型的指针;

  • 参数二,指向要复制的数据源的指针,类型转换为 const void* 类型的指针;

  • 参数三,要复制的字节数,size_t 是无符号整数类型;

  • 返回值,返回目标数组的指针。

1.功能:复制内存块

  • 将sum字节数的值从源指向的位置直接复制到目标指向的内存块。

  • 源指针和目标指针指向的对象的基础类型与此函数无关;结果是数据的二进制副本。

  • 该函数不检查源中的任何终止空字符 - 它总是准确地复制字节数。

  • 为避免溢出,目标和源参数指向的数组大小应至少为字节数,并且不应重叠(对于重叠的内存块,memmove 是一种更安全的方法)。

#include <string.h>
#include <stdio.h>
int main()
{
    int arr[10] = {1,2,3,4,5,6,7,8};
    int abb[10] = { 0 };
    memcpy(abb, arr, 32);
    for (int i = 0; i < 10; i++)
    {
        printf("%d ", abb[i]);
    }
    return 0;
}

2.注意

①在内存重叠时,使用memcpy可能出现意想不到的效果(编译器不同可能产生不同的效果,VS下并不会产生该效果)

void* my_memcpy(void* str1, const void* str2, size_t num)
{
    assert(str1 && str2);
    void* s = str1;
    while(*((char*)str1 + num) = *((char*)str2 + num),num--)
    {
        ;
    }
    return s;
}
int main()
{
    int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
    my_memcpy(arr, arr + 2, 20);
    for (int i = 0; i < 10; i++)
    {
        printf("%d ", arr[i]);
    }
    return 0;
}

建议:在内存重叠的时候使用memmove函数

3.模拟实现

void* my_memcpy(void* str1, const void* str2, size_t num)
{
    assert(str1 && str2);
    void* s = str1;
    while(*((char*)str1 + num) = *((char*)str2 + num),num--)
    {
        ;
    }
    return s;
}
int main()
{
    int arr[10] = {1,2,3,4,5,6,7,8};
    int abb[10] = { 0 };
    my_memcpy(abb, arr, 32);
    for (int i = 0; i < 10; i++)
    {
        printf("%d ", abb[i]);
    }
    return 0;
}

十三、memmove

void * memmove ( void * destination, const void * source, size_t num );

  • 参数一,指向要在其中复制内容的目标数组的指针,类型转换为 void* 类型的指针。

  • 参数二,指向要复制的数据源的指针,类型转换为 const void* 类型的指针。

  • 参数三,要复制的字节数。size_t 是无符号整数类型。

  • 返回值,返回目标数组的指针。

1.功能:移动内存块

  • 字节数的值从源指向的位置复制到目标指向的内存块。复制就像使用了中间缓冲区一样,允许目标和源重叠

  • 源指针和目标指针指向的对象的基础类型与此函数无关;结果是数据的二进制副本。

  • 该函数不检查源中的任何终止空字符 - 它总是准确地复制字节数。

  • 为避免溢出,目标参数和源参数指向的数组的大小应至少为字节数。

int main()
{
    int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
    memmove(arr, arr + 2, 20);
    for (int i = 0; i < 10; i++)
    {
        printf("%d ", arr[i]);
    }
    return 0;
}

2.模拟实现

#include <stdio.h>
#include <string.h>
void* my_memmove(void* dest, const void* src, size_t num)
{
    void* s = dest;
    char* f = (char*)dest;
    char* t = (char*)src;
    if (dest > src)
    {
        while (*(f + num) = *(t + num), num--)
        {
            ;
        }
    }
    else
    {
        while (*f++ = *t++, num--)
        {
            ;
        }
    }
    return s;
}
int main()
{
    int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
    my_memmove(arr+2, arr, 20);
    for (int i = 0; i < 10; i++)
    {
        printf("%d ", arr[i]);
    }
    return 0;
}

十四、memcmp

int memcmp ( const void * ptr1, const void * ptr2, size_t num );

参数一,指向内存块的指针。

参数二,指向内存块的指针。

参数三,要比较的字节数。

返回值,返回一个整数值,该值指示内存块内容之间的关系:

1.功能:比较两个内存块

将 ptr1 指向的内存块的前 num 字节数与 ptr2 指向的第一个字节数进行比较,如果它们都匹配,则返回零,如果不匹配,则返回一个不同于零的值,表示哪个值更大。 请注意,与 strcmp 不同,该函数在找到空字符后不会停止比较。

#include <stdio.h>
#include <string.h>
int main()
{
    int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
    int add[10] = { 1,2,3,4,6 };
    printf("%d\n", memcmp(arr, add, 16));
    return 0;
}
#include <stdio.h>
#include <string.h>
int main()
{
    int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
    int add[10] = { 1,2,3,4,6 };
    printf("%d\n", memcmp(arr, add, 17));
    return 0;
}

十五、memset

void * memset ( void * ptr, int value, size_t num );

  • 参数一,指向要填充的内存块的指针。

  • 参数二,要设置的值。该值作为 int 传递,但该函数使用此值的无符号 char 转换填充内存块。

  • 参数三,要设置为该值的字节数。size_t 是无符号整数类型。

  • 返回值,返回 PTR

1.功能:填充内存块

将 ptr 指向的内存块的num个字节数设置为指定值(解释为无符号字符)。

#include <stdio.h>
#include <string.h>
int main()
{
    char arr[10] = "abcdefg";
    memset(arr, 'x', 3);
    printf("%s\n", arr);
    return 0;
}

2.注意

①memst以字节为单位设置内存

#include <stdio.h>
#include <string.h>
int main()
{
    int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
    memset(arr, 1, 40);
    for (int i = 0; i < 10; i++)
    {
        printf("%x ", arr[i]);
    }
    return 0;
}

a

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值