系列文章目录:
字符函数和字符串函数详解(一)strlen strcpy strcat strcmp
字符函数和字符串函数详解(二)strncpy strncat strncmp strstr strtok(及其模拟实现)
字符函数和字符串函数详解(三)strerror memcpy memmove memset memcmp(及部分字符分类函数)
目录
这一期主要介绍打印错误信息的函数和 内存操作函数,简单介绍一下字符操作函数(可熟练使用就行)
一.错误信息报告
strerror函数的使用
在c语言中定义了错误码0 1 2 3 4 ,打印出来的小效果如下图片所示:
errno 是C语言提供的全局的错误变量 使用时需要包含头文件 #include <errno.h> ,当我们使用某个函数时报错,会将对应的错误码赋给errno,此时我们可以使用strerror函数打印对应的错误信息。
代码示例:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<String.h>
#include <errno.h>
int main()
{
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen:"); //稍后再说
printf("%s\n", strerror(errno));//打印的是errno变量中错误码对应的错误信息
return 1;
}
//读文件
fclose(pf);
pf = NULL;
return 0;
}
运行结果:
细心的小伙伴会发现,我在代码中使用了 perror(“fopen:”); 这样的一句代码,其实perror函数是用来给错误信息添加描述的
可以理解为 “ 描述信息+strerror(errno) ; ”
二.内存操作函数
1.memcpy
void* memcpy (void* destination, const void* source, size_t num );
(1)memcpy的使用
我们将memcpy函数称之为内存拷贝函数,将num字节的值从source指向的位置直接复制到 destination 所指向的内存块。
代码示例:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
int main()
{
int destination[10] = {
0 };
int source[10] = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
memcpy(destination, source, 8);
//float arr1[] = { 1.0f,2.0f,3.0f,4.0f };
//float arr2[5] = { 0.0 };
//memcpy(arr2, arr1, 8);
return 0;
}
与strcpy不同的是,memcpy是以内存为单位进行拷贝,并且不以终止符 \0 作为自己的结束标志,换言之memcpy没有结束标志,所以它会直接拷贝到num个才会结束。
另外memcpy不用于拷贝出现重叠的俩个内存块,俩个重叠的内存块的拷贝一般使用memmove函数,会在下一个函数介绍什么是内存重叠,如何使用 memmove。
(2)memcpy的模拟实现
void* My_memcpy(void* destination,const void* source, size_t num)
{
assert(destination);
assert(source);
void* ret = destination;
while (num--)
{
* ((char*)destination)++ = *((char*)source)++;
}
return ret;
}
int main()
{
char arr[18] = "0000000000000000";
char arr1[] = "abcdefg sd a da s da";
printf("%s",My_memcpy(arr,arr1,6));
return 0;
}
运行结果:
2.memmove
void* memmove (void* destination, const void* source, size_t num );
(1)memmove的使用
memmove和memcpy一样也是内存拷贝函数,但与其不同的地方是,memmove可以处理内存重叠的情况;接下来介绍内存重叠的情况;
所以当拷贝时存在内存重叠时,应当使用memmove函数去实现。
代码示例:
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[] = "11223344556677";
printf("%s", memmove(arr1, arr1+2, 6));
return 0;
}
运行结果:
(2)memmove的模拟实现
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>
void* My_memmove(void* destination,const void* source,size_t num)
{
assert(destination);
assert(source);
void* ret = destination;
if (destination <= source)
{
while (num--)
{
*((char*)destination)++ = *((char*)source)++;
}
}
else
{
while (num--)
{
char* des = (char*)destination + num - 1;
char* sou = (char*)source + num - 1;
*(des) = *(sou);
}
}
return (char*)ret;
}
int main()
{
char arr1[] = "11223344556677";
printf("%s", My_memmove(arr1, arr1+2, 6));
return 0;
}
运行结果:
3.memset
void* memset (void* ptr, int value, size_t num );
memset的使用
memset是计算机中C/C++语言初始化函数。 作用是将某一块内存中的内容全部设置为指定的值, 这个函数通常为新申请的内存做初始化工作。作用是在一段内存块中填充某个给定的值,它是对较大的 结构体 或 数组 进行清零操作的一种最快方法.
代码示例:
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] = "abcdefg";
memset (str,'-',6);
puts (str);
return 0;
}
运行结果:
4.memcmp
void* memcmp (const void* ptr1, const void* ptr2, size_t num );
memcmp的使用
memcmp用来比较两个内存块。将 ptr1 所指向的内存块的前一个数字字节与 ptr2 所指向的前一个数字字节进行比较,如果它们全部匹配,则返回零,或者返回一个不同于零的值,如果它们不匹配,则表示哪个值更大。
返回值 | 表明 |
---|---|
返回值>0 | 在两个内存块中不匹配的第一个字节在 ptr1 中的值低于在 ptr2 中的值(如果计算为无符号字符值) |
返回值=0 | 两个内存块的内容相等 |
返回值<0 | 在两个内存块中都不匹配的第一个字节在 ptr1 中的值大于在 ptr2 中的值(如果计算为无符号字符值) |
代码示例: |
#include <stdio.h>
#include <string.h>
int main ()
{
char buffer1[] = "DWgaOtP12df0";
char buffer2[] = "DWGAOTP12DF0";
int n;
n=memcmp ( buffer1, buffer2, sizeof(buffer1) );
if (n>0) printf ("'%s' is greater than '%s'.\n",buffer1,buffer2);
else if (n<0) printf ("'%s' is less than '%s'.\n",buffer1,buffer2);
else printf ("'%s' is the same as '%s'.\n",buffer1,buffer2);
return 0;
}
运行结果:
三.字符函数
字符函数使用时需要包含"#include <ctype.h>"
1.字符分类函数
2.字符转换函数
int tolower ( int c );
int toupper ( int c );
代码示例:
#include <stdio.h>
#include <ctype.h>
int main()
{
int i = 0;
char str[] = "Test String.\n";
char c;
while (str[i])
{
c = str[i];
if (isupper(c))
c = tolower(c);
putchar(c);
i++;
}
return 0;
}
注:有多努力就有多特殊。