字符串函数(二)与内存函数

简介:

strncpy

strcpystrncpy 都是 C 标准库中用于复制字符串的函数,它们有一些不同之处

strcpy 函数用于将一个字符串复制到另一个字符串中,直到遇到字符串结束标志 \0。

char* strcpy(char* dest, const char* src);


strcpy 函数将 src 指向的字符串复制到 dest 指向的字符串中,直到遇到 \0 为止。需要确保目标字符串 dest 至少有足够的空间来容纳被复制的字符串,否则可能发生缓冲区溢出。


strncpy 函数也用于复制字符串,但是它允许指定要复制的最大字节数。


char* strncpy(char* dest, const char* src, size_t n);


strncpy 函数将 src 指向的字符串中最多 n 个字符复制到 dest 指向的字符串中。如果 src 的长度小于 n,则 dest 中剩余的字符将被补充为 \0。需要注意的是,如果 src 的长度大于 n,则 dest 不会被自动添加 \0 结尾符。因此,在使用 strncpy 时,可能需要手动在目标字符串的结尾添加 \0

以下是两个函数的示例:


#include 
#include 
int main() {
    char src[] = "Hello, World!";
    char dest1[20];
    char dest2[20];
    strcpy(dest1, src);
    printf("%s\n", dest1);
    strncpy(dest2, src, 5);
    dest2[5] = '\0'; // 手动添加字符串结束符
    printf("%s\n", dest2);
    return 0;
}


模拟实现


char* my_strncpy(char* dest, const char* src, size_t n) {
    char* d = dest;
    const char* s = src;
   
    while (n > 0 && *s != '\0') {
        *d++ = *s++;
        n--;
    }
   
    while (n > 0) {
        *d++ = '\0';  // 将剩余的空间填充为'\0'
        n--;
    }
   
    return dest;
}


strncat函数的使用与模拟实现

我们从一个示例入手,其与strcat十分相似,但是限制了字符个数:


int main() {
    char dest[20] = "Hello, ";
    char src[] = "World!";
    strcat(dest, src);
    printf("strcat result: %s\n", dest);
    char dest2[20] = "Hello, ";
    char src2[] = "World!";
    strncat(dest2, src2, 3);
    printf("strncat result: %s\n", dest2);
    return 0;
}


输出结果如下


strcat result: Hello, World!
strncat result: Hello, Wor


模拟实现


char* my_strncat(char* dest, const char* src, size_t n) {
    char* d = dest;
    const char* s = src;
    // 定位到目标字符串的结尾
    while (*d != '\0') {
        d++;
    }
    // 将 src 的前 n 个字符连接到 dest 的末尾
    while (n > 0 && *s != '\0') {
        *d++ = *s++;
        --n;
    }
    *d = '\0';  // 添加字符串结束符
    return dest;
}

strtok函数的使用

strtok 函数是 C 语言中用于字符串分割的函数,它可以将一个字符串分割成多个子字符串。strtok 函数具有以下形式的原型:


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

函数的第一个参数 str 是要分割的字符串,第二个参数 sep 是分隔符字符串,用于指定在哪些字符处分割原始字符串。函数会返回分割后的子字符串。


当第一次调用 strtok 时,会将 str 参数指向的字符串分割成子字符串。接下来,如果将 strtok 函数的第一个参数传递为 NULL,函数将会继续在剩余的字符串中查找下一个子字符串。


示例如下:


#include 
#include 
int main() {
    char str[] = "The-quick-brown-fox";
    const char sep[] = "-";
    char *token = strtok(str, sep);  // 第一次调用 strtok
    while (token != NULL) {
        printf("%s\n", token);
        token = strtok(NULL, sep);  // 后续调用 strtok
    }
    return 0;
}


strtok函数也可以模拟实现,但较之前略微复杂


char* my_strtok(char* str, const char* delim, int* pos) {
    if (str == NULL) {
        str = (char*)malloc(strlen(str));
        strcpy(str, pos);
    }
    // 跳过分隔符
    while (str[*pos] != '\0' && strchr(delim, str[*pos]) != NULL) {
        (*pos)++;
    }
    if (str[*pos] == '\0') {
        return NULL;  // 到达了字符串末尾
    }
    char* start = str + *pos;  // 记录子字符串的起始位置
    while (str[*pos] != '\0' && strchr(delim, str[*pos]) == NULL) {
        (*pos)++;
    }
    if (str[*pos] != '\0') {
        str[*pos] = '\0';  // 在分隔符处截断字符串
        (*pos)++;
    }
    return start;  // 返回分割后的子字符串
}

————————————————

会使用即可


strerror函数的使用

strerror 函数是C标准库中的一个函数,它用于将系统错误码转换为描述性的错误消息字符串。该函数的原型如下:


  1. char * strerror ( int errnum );


其中,errnum 是表示系统错误码的整数。strerror 函数将返回一个指针,指向包含了对应于错误码的错误消息字符串。


通常情况下,当某个系统调用或库函数返回一个错误码时,可以使用 strerror 函数来获取对该错误的描述。例如,在您之前提到的文件打开失败的例子中,strerror(errno) 会返回一个描述由 errno 表示的错误的字符串。


下面是一个使用 strerror 函数的示例:


#include 
#include 
#include 
int main() {
    FILE *pFile;
    pFile = fopen("unexist.ent", "r");
 
    if (pFile == NULL) {
        printf("Error opening file: %s\n", strerror(errno));
    }
    return 0;
}


在这个示例中,strerror(errno) 会返回一个描述由 errno 表示的错误的字符串。如果文件打开失败,则会输出包含了错误描述的消息。


Error opening file unexist.ent: No such file or directory


perror函数的使用

perror 是一个用于输出描述性错误消息的C标准库函数。它通常用于在程序中打印出最近的错误信息,同时会附带一个自定义的错误消息字符串


示例如下:

1. #include 
2. #include 
3. #include 
4. 
5. int main() {
6.     FILE *pFile;
7.     pFile = fopen("unexist.ent", "r");
8.  
9.     if (pFile == NULL) {
10.         perror("Error opening file");
11.     }
12. 
13.     return 0;
14. }


perror 函数将输出一个包含了自定义描述以及错误消息的信息。例如,它可能会输出 “Error opening file: No such file or directory”,其中 “No such file or directory” 是由全局变量 errno 表示的错误消息。


内存函数

memcpy函数的使用与模拟实现

memcpy 是 C 语言中用于内存拷贝的函数,它能够将源内存块的内容复制到目标内存块中。memcpy 函数的原型如下:


void *memcpy(void *dest, const void *src, size_t n);


其中,dest 是指向目标内存块的指针,src 是指向源内存块的指针,n 则是要被复制的字节数。


memcpy 函数会从源内存块中复制 n 个字节的内容到目标内存块中。需要注意的是,memcpy 仅仅是简单的字节拷贝,不对复制的内容做任何解释或者转换

如果src和dest有任何的重叠,复制的结果都是未定义的.


1. #include 
2. #include 
3. int main()
4. {
5.  int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
6.  int arr2[10] = { 0 };
7.  memcpy(arr2, arr1, 20);
8.  int i = 0;
9.  for (i = 0; i < 10; i++)
10.  {
11.  printf("%d ", arr2[i]);
12.  }
13.  return 0; 
14. }

结果为 1 2 3 4 5 0 0 0 0 0;


模拟实现

1. void* memcpy(void* dst, const void* src, size_t count)
2. {
3.  void* ret = dst;
4.  assert(dst);
5.  assert(src);
6. 
7.  while (count--) {
8.   *(char*)dst = *(char*)src;
9.   dst = (char*)dst + 1;
10.   src = (char*)src + 1;
11.   }
12.   return(ret);
13. }

memmove函数的使用与模拟实现

memmove函数与memcpy函数很相似,但是memmove函数无论是否重叠,都能保证其准确性;

其原型与memcpy相同:


void *memcpy(void *dest, const void *src, size_t n);


示例代码如下


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


输出结果如下


1 2 1 2 3 4 5 8 9 10

模拟实现


void* my_memmove(void* dest, const void* src, size_t n) {
    char* d = (char*)dest;
    const char* s = (const char*)src;
    if (s < d && s + n > d) {
        // 发生了重叠,需要向后复制
        s += n;
        d += n;
        while (n--) {
            *(--d) = *(--s);
        }
    }
    else {
        // 没有重叠,直接按顺序复制
        while (n--) {
            *d++ = *s++;
        }
    }
    return dest;
}

memset函数的使用

memset 是 C 标准库中的一个函数,用于将一块内存的内容设置为指定的值。memset 函数的原型如下:


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


其中,ptr 是指向要被设置的内存块的指针,value 是要设置的值,num 则是要设置的字节数。


memset 函数将会把 ptr 指向的内存块的前 num 个字节设置为 value。


以下是一个简单的示例:


#include 
#include 
int main ()
{
 char str[] = "hello world";
 memset (str,'x',6);
 printf(str);
 return 0;
}


输出结果:


xxxxxxworld


memcmp函数的使用

memcmp 是 C 标准库中的一个函数,用于比较两块内存区域的内容。memcmp 函数的原型如下:


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


ptr1 和 ptr2 是分别指向要进行比较的两个内存区域的指针,num 是要比较的字节数。


memcmp 函数将会根据字典顺序比较这两个内存区域的内容。具体而言,它会逐个比较每个指针所指向的字节,直到发现不相等的字节;或者比较完所有的字节。如果两个内存区域在前 num 个字节上的内容相同,则返回值为 0;如果两个内存区域在前 num 个字节上的内容不同,则返回值可能是大于 0 或者小于 0.


示例如下:


#include 
#include 
int main() {
    char str1[] = "Hello";
    char str2[] = "World";
    if (memcmp(str1, str2, 5) == 0) {
        printf("The first 5 characters are the same.\n");
    } else {
        printf("The first 5 characters are different.\n");
    }
    return 0;
}

结果

The first 5 characters are different.



                      感谢观看

相关文章
|
17天前
|
程序员 C语言
C语言库函数 — 内存函数(含模拟实现内存函数)
C语言库函数 — 内存函数(含模拟实现内存函数)
27 0
|
27天前
|
编译器 C语言 C++
【C语言】memset()函数(内存块初始化函数)
【C语言】memset()函数(内存块初始化函数)
26 0
|
27天前
|
编译器 C语言 C++
【C语言】memcpy()函数(内存块拷贝函数)
【C语言】memcpy()函数(内存块拷贝函数)
42 0
|
5天前
|
编译器 C语言
字符串与内存函数
字符串与内存函数
19 0
|
2天前
|
C语言
C语言:内存函数(memcpy memmove memset memcmp使用)
C语言:内存函数(memcpy memmove memset memcmp使用)
|
27天前
|
编译器 C语言 C++
【C语言】calloc()函数详解(动态内存开辟函数)
【C语言】calloc()函数详解(动态内存开辟函数)
25 0
|
27天前
|
存储 前端开发 编译器
【C语言】memmove()函数(拷贝重叠内存块函数详解)
【C语言】memmove()函数(拷贝重叠内存块函数详解)
33 1
|
30天前
|
安全 程序员 C++
【C++ 基本知识】现代C++内存管理:探究std::make_系列函数的力量
【C++ 基本知识】现代C++内存管理:探究std::make_系列函数的力量
101 0
|
1月前
|
存储 程序员 Shell
【C/C++ 内存管理函数】C语言动态内存管理大揭秘:malloc、calloc、realloc与new的对比与差异
【C/C++ 内存管理函数】C语言动态内存管理大揭秘:malloc、calloc、realloc与new的对比与差异
175 0
|
1月前
|
存储 JSON 监控
Higress Controller**不是将配置信息推送到Istio的内存存储里面的**。
【2月更文挑战第30天】Higress Controller**不是将配置信息推送到Istio的内存存储里面的**。
14 1