前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >字符串函数(二)与内存函数

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

作者头像
用户11029103
发布2024-03-19 15:28:04
670
发布2024-03-19 15:28:04
举报
文章被收录于专栏:技术学习技术学习

strncpy

strcpystrncpy 都是 C 标准库中用于复制字符串的函数,它们有一些不同之处 strcpy 函数用于将一个字符串复制到另一个字符串中,直到遇到字符串结束标志 \0。

代码语言:javascript
复制
char* strcpy(char* dest, const char* src);

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

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

代码语言:javascript
复制
char* strncpy(char* dest, const char* src, size_t n);

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

代码语言:javascript
复制
#include <stdio.h>
#include <string.h>

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;
}

模拟实现

代码语言:javascript
复制
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十分相似,但是限制了字符个数:

代码语言:javascript
复制
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;
}

输出结果如下

代码语言:javascript
复制
strcat result: Hello, World!
strncat result: Hello, Wor

模拟实现

代码语言:javascript
复制
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 函数具有以下形式的原型:

代码语言:javascript
复制
char *strtok(char *str, const char *sep);

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

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

示例如下:

代码语言:javascript
复制
#include <stdio.h>
#include <string.h>

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函数也可以模拟实现,但较之前略微复杂

代码语言:javascript
复制
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标准库中的一个函数,它用于将系统错误码转换为描述性的错误消息字符串。该函数的原型如下:

代码语言:javascript
复制
char * strerror ( int errnum );

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

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

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

代码语言:javascript
复制
#include <stdio.h>
#include <string.h>
#include <errno.h>

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 表示的错误的字符串。如果文件打开失败,则会输出包含了错误描述的消息。

代码语言:javascript
复制
Error opening file unexist.ent: No such file or directory

perror函数的使用

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

示例如下:

代码语言:javascript
复制
#include <stdio.h>
#include <string.h>
#include <errno.h>

int main() {
    FILE *pFile;
    pFile = fopen("unexist.ent", "r");
  
    if (pFile == NULL) {
        perror("Error opening file");
    }

    return 0;
}

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

内存函数

memcpy函数的使用与模拟实现

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

代码语言:javascript
复制
void *memcpy(void *dest, const void *src, size_t n);

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

memcpy 函数会从源内存块中复制 n 个字节的内容到目标内存块中。需要注意的是,memcpy 仅仅是简单的字节拷贝,不对复制的内容做任何解释或者转换 如果src和dest有任何的重叠,复制的结果都是未定义的.

代码语言:javascript
复制
#include <stdio.h>
#include <string.h>
int main()
{
 int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
 int arr2[10] = { 0 };
 memcpy(arr2, arr1, 20);
 int i = 0;
 for (i = 0; i < 10; i++)
 {
 printf("%d ", arr2[i]);
 }
 return 0; 
}

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

模拟实现

代码语言:javascript
复制
void* memcpy(void* dst, const void* src, size_t count)
{
	void* ret = dst;
	assert(dst);
	assert(src);
	
	while (count--) {
		*(char*)dst = *(char*)src;
		dst = (char*)dst + 1;
		src = (char*)src + 1;
	}
	return(ret);
}

memmove函数的使用与模拟实现

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

代码语言:javascript
复制
void *memcpy(void *dest, const void *src, size_t n);

示例代码如下

代码语言:javascript
复制
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;
}

输出结果如下

代码语言:javascript
复制
1 2 1 2 3 4 5 8 9 10

模拟实现

代码语言:javascript
复制
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 函数的原型如下:

代码语言:javascript
复制
void *memset(void *ptr, int value, size_t num);

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

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

以下是一个简单的示例:

代码语言:javascript
复制
#include <stdio.h>
#include <string.h>
int main ()
{
 char str[] = "hello world";
 memset (str,'x',6);
 printf(str);
 return 0;
}

输出结果:

代码语言:javascript
复制
 xxxxxxworld

memcmp函数的使用

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

代码语言:javascript
复制
int memcmp(const void *ptr1, const void *ptr2, size_t num);

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

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

示例如下:

代码语言:javascript
复制
#include <stdio.h>
#include <string.h>

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;
}

结果

代码语言:javascript
复制
The first 5 characters are different.

感谢观看,求点赞和关注❥,我会继续更新有关c语言的内容!

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2024-03-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • strncpy
  • strncat函数的使用与模拟实现
  • strtok函数的使用
  • strerror函数的使用
  • perror函数的使用
  • 内存函数
  • memcpy函数的使用与模拟实现
  • memmove函数的使用与模拟实现
  • memset函数的使用
  • memcmp函数的使用
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档