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 <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;
}
模拟实现
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;
}
我们从一个示例入手,其与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 函数是 C 语言中用于字符串分割的函数,它可以将一个字符串分割成多个子字符串。strtok 函数具有以下形式的原型:
char *strtok(char *str, const char *sep);
函数的第一个参数 str 是要分割的字符串,第二个参数 sep 是分隔符字符串,用于指定在哪些字符处分割原始字符串。函数会返回分割后的子字符串。
当第一次调用 strtok 时,会将 str 参数指向的字符串分割成子字符串。接下来,如果将 strtok 函数的第一个参数传递为 NULL,函数将会继续在剩余的字符串中查找下一个子字符串。
示例如下:
#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函数也可以模拟实现,但较之前略微复杂
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 函数是C标准库中的一个函数,它用于将系统错误码转换为描述性的错误消息字符串。该函数的原型如下:
char * strerror ( int errnum );
其中,errnum 是表示系统错误码的整数。strerror 函数将返回一个指针,指向包含了对应于错误码的错误消息字符串。
通常情况下,当某个系统调用或库函数返回一个错误码时,可以使用 strerror 函数来获取对该错误的描述。例如,在您之前提到的文件打开失败的例子中,strerror(errno) 会返回一个描述由 errno 表示的错误的字符串。
下面是一个使用 strerror 函数的示例:
#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 表示的错误的字符串。如果文件打开失败,则会输出包含了错误描述的消息。
Error opening file unexist.ent: No such file or directory
perror 是一个用于输出描述性错误消息的C标准库函数。它通常用于在程序中打印出最近的错误信息,同时会附带一个自定义的错误消息字符串
示例如下:
#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 是 C 语言中用于内存拷贝的函数,它能够将源内存块的内容复制到目标内存块中。memcpy 函数的原型如下:
void *memcpy(void *dest, const void *src, size_t n);
其中,dest 是指向目标内存块的指针,src 是指向源内存块的指针,n 则是要被复制的字节数。
memcpy 函数会从源内存块中复制 n 个字节的内容到目标内存块中。需要注意的是,memcpy 仅仅是简单的字节拷贝,不对复制的内容做任何解释或者转换 如果src和dest有任何的重叠,复制的结果都是未定义的.
#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;
模拟实现
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函数与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 是 C 标准库中的一个函数,用于将一块内存的内容设置为指定的值。memset 函数的原型如下:
void *memset(void *ptr, int value, size_t num);
其中,ptr 是指向要被设置的内存块的指针,value 是要设置的值,num 则是要设置的字节数。
memset 函数将会把 ptr 指向的内存块的前 num 个字节设置为 value。
以下是一个简单的示例:
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] = "hello world";
memset (str,'x',6);
printf(str);
return 0;
}
输出结果:
xxxxxxworld
memcmp 是 C 标准库中的一个函数,用于比较两块内存区域的内容。memcmp 函数的原型如下:
int memcmp(const void *ptr1, const void *ptr2, size_t num);
ptr1 和 ptr2 是分别指向要进行比较的两个内存区域的指针,num 是要比较的字节数。
memcmp 函数将会根据字典顺序比较这两个内存区域的内容。具体而言,它会逐个比较每个指针所指向的字节,直到发现不相等的字节;或者比较完所有的字节。如果两个内存区域在前 num 个字节上的内容相同,则返回值为 0;如果两个内存区域在前 num 个字节上的内容不同,则返回值可能是大于 0 或者小于 0.
示例如下:
#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;
}
结果
The first 5 characters are different.
感谢观看,求点赞和关注❥,我会继续更新有关c语言的内容!