strncpy
strcpy 和 strncpy 都是 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标准库中的一个函数,它用于将系统错误码转换为描述性的错误消息字符串。该函数的原型如下:
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.
感谢观看