草庐IT

strtok,strerror,memcpy,memmove,memcmp,memset详细解析及模拟实现

ᰔᩚ. 一怀明月ꦿ 2023-10-27 原文
​​​​​​​

🐶博主主页:@ᰔᩚ. 一怀明月ꦿ 

❤️‍🔥专栏系列:线性代数C初学者入门训练题解CC的使用文章

🔥座右铭:“不要等到什么都没有了,才下定决心去做”

🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀

目录

🐰strtok

🐰strerror

🐰memcpy

🐰模拟实现memcpy

🐰memmove

🐰模拟实现memmove

🐰memcmp

🐰memset


🐰strtok

strtok用于字符串的拆分,引用头文件为#include<string.h>

strtok的原型:

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

str:字符串的首地址

 delimiters:分隔符

注意:返回类型是字符串的首地址

以下就是把2695855992.@qq.com分割成2695855992 qq com

"@.":分隔符

"@."分隔符
#include<stdio.h>
#include<string.h>
int main()
{
    char arr[]="2695855992.@qq.com";
    char buf[30]={0};
    strcpy(buf,arr);
//    char* str=strtok(buf,"@.");//第一次调用时传字符串的首地址
//    printf("%s\n",str);
//    str=strtok(NULL,"@.");//第二次调用时传空指针
//    printf("%s\n",str);
//    str=strtok(NULL,"@.");//依次类推,只要不是第一次都得穿空指针
//    printf("%s\n",str);
    for(char* str=strtok(buf,"@.");str!=NULL;str=strtok(NULL,"@."))//这里使用循环达到以上一样的效果
    {
        printf("%s\n",str);
    }
    return 0;
}

假如字符串是"aaa-bbb-ccc"

1.第一次调用strtok(),传入的参数str是要被分割的字符串{aaa - bbb -ccc},而成功后返回的是第一个子字符串{aaa};

2.而第二次调用strtok的时候,传入的第一个参数应该为NULL,使得该函数默认使用上一次未分割完的字符串继续分割 ,就从上一次分割的位置{aaa-}作为本次分割的起始位置,直到分割结束。

二.注意事项

这里首先需要强调的是strtok函数在进行字符串分解的时候,其第一个参数,即str是在变化的,就像前面说过的一样,其只是对原字符串(str)进行了调整,也就是改变了原字符串。由上面的例子来看,""2695855992@qq.com"是源字符串,在调用strtok对其分解结束后,字符串变成了"26958559920qq0com",其中的' @ ', ' . '替换成了'\0',也就是替换成了字符串结束标志字符,这样在打印或使用的时候都会使得前面的字符串成为一个看起来独立的字符串,即"2695855992"、"qq"、"com",这些字符串还是在源字符串中,只是后面都有了自己的字符串结束标志'\0'而已。

还有一点,strtok的第一个参数不能是常量字符串的指针,由于上面我们提到,strtok分割函数时,是要对原字符串做出改变的,但传入的是常量字符串,是无法做出改变的,从而导致错误

🐰strerror

strerror用于调用库函数失败时翻译错误信息,引用的头文件#include<string.h>

strerror的原型:


char * strerror ( int errnum );

errnum:调用库函数失败,返回的错误码

注意:返回错误码所对应的错误信息的首地址

#include<stdio.h>
#include<string.h>
#include<errno.h>
int main()
{
    FILE* pf=fopen("duck.txt.", "r");
    if(pf==NULL)
    {
        printf("%s\n",strerror(errno));//errno是一个全局变量,类型为整形,erron是一个错误码,系统调用出错的时候,会设置一个错误码。因为C语言没有异常处理机制,所以要依靠错误码进行异常情况的处理。
    }
    return 0;
}

我的电脑中没有duck.txt这个文件,所以它会返回一个错误的信息说的就是不存在这样的文件,这就是strerror对错误码翻译

 其实我们还可以自己定义错误码,去查看错误码在库函数所对应的信息,例如

#include<stdio.h>
#include<string.h>
int main()
{
    printf("%s\n",strerror(0));
    printf("%s\n",strerror(1));
    printf("%s\n",strerror(2));
    printf("%s\n",strerror(3));
    printf("%s\n",strerror(4));
    printf("%s\n",strerror(5));
    printf("%s\n",strerror(6));
    printf("%s\n",strerror(7));
    printf("%s\n",strerror(8));
    return 0;
}

🐰memcpy

memcpy用于内存拷贝(什么类型数据都可以),引用头文件#include<string.h>

memcpy的原型:

void * memcpy ( void * destination, const void * source, size_t num );

 destination:目标空间

source:拷贝空间

num:拷贝字节数

注意:返回目标空间的首地址​​​​​​​

注:void*是通用指针类型,可以接受任意类型的数据,不能进行解引用操作

#include<stdio.h>
#include<string.h>
int main()
{
    int arr[]={1,2,3,4,5,6,7,8,9,0};
    int brr[20]={0};
    memcpy(brr,arr,20);//在arr中拷贝了20个字节
    for(int i=0;i<5;i++)
    {
        printf("%d ",brr[i]);
    }
    return 0;
}
结果:1 2 3 4 5

🐰模拟实现memcpy

#include<stdio.h>
#include<string.h>
void* my_memcpy(void* dest,void* src,size_t num)//将传入数据类型强制转化为字符类型,然后一个字节一个字节进行拷贝,这样就可以实现任何数据类型的拷贝
{
    void* ret=dest;
    while(num--)
    {
        *(char*)dest=*(char*)src;
        dest=(char*)dest+1;
        src=(char*)src+1;
    }
   return ret;
}
int main()
{
    int arr[]={1,2,3,4,5,6,7,8,9,0};
    int brr[20]={0};
    my_memcpy(brr,arr,20);
    for(int i=0;i<5;i++)
    {
        printf("%d ",brr[i]);
    }
    return 0;
}

🐰memmove

memove用于内存的拷贝(和memcpy一样实现内存拷贝,但是由于编译器的原因,memcpy不能实现拷贝空间和目标空间在一个空间,而memmove可以实现),引用头文件#include<string.h>

memove的原型:

void * memmove ( void * destination, const void * source, size_t num );

destination:目标空间

source:拷贝空间

num:拷贝字节数

注意:返回目标空间的首地址​​​​​​​

#include<stdio.h>
#include<string.h>
int main()
{
    int arr[]={1,2,3,4,5,6,7,8,9,0};
    int brr[20]={0};
    memmove(arr+2,arr,20);
    for(int i=0;i<5;i++)
    {
        printf("%d ",arr[i]);
    }
    return 0;
}

🐰模拟实现memmove

#include<stdio.h>
#include<string.h>
void* my_memmove(void* dest,void* src,size_t num)
{
    void* ret=dest;
    if(dest>src)//如果目标空间的首地址大于拷贝空间的首地址,就得实现从后往前拷贝
    {
        while(num--)
        {
            *((char*)dest+num)=*((char*)src+num);//一个字节一字节拷贝
        }
    }
    else{
        while(num--)//如果目标空间的首地址小于或等于拷贝空间的首地址,就得实现从前往后拷贝
        //一个字节一字节拷贝        
        {
            *(char*)dest=*(char*)src;
            dest=(char*)dest+1;
            src=(char*)src+1;
        }
    }
    return ret;
}
int main()
{
    int arr[]={1,2,3,4,5,6,7,8,9,0};
    int brr[20]={0};
    my_memmove(arr,arr+2,20);
    for(int i=0;i<5;i++)
    {
        printf("%d ",arr[i]);
    }
    return 0;
}

🐰memcmp

memcmp用于空间的比较函数(字符类型,整形,浮点型...),引用头文件#include<string.h>

memcmp的原型:

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

 ptr1:比较的空间的首地址 

ptr2:比较空间的首地址

num:比较的字节数

注意:返回类型为整形    

ptr1>ptr2 返回大于0的数

ptr1==ptr2返回0

ptr1<ptr2   返回小于0的数

🐰memset

memset用于空间设置函数,引用头文件#include<string.h>

memset的原型:​​​​​​​

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

ptr:设置的空间

value:设置成的值

num:设置的字节数

注意:返回设置空间的首地址

#include<stdio.h>
#include<string.h>
int main()
{
    int arr[]={1,2,3,4,7};//01 00 00 00 02 00 00 00
    memset(arr,0,5);//将arr的5个字节设置成0
    for(int i=0;i<5;i++)
    {
        printf("%d ",arr[i]);
    }
    return 0;
}
结果:0 0 3 4 7

🌸🌸🌸如果大家还有不懂或者建议都可以发在评论区,我们共同探讨,共同学习,共同进步。谢谢大家! 🌸🌸🌸   

有关strtok,strerror,memcpy,memmove,memcmp,memset详细解析及模拟实现的更多相关文章

  1. Ruby 解析字符串 - 2

    我有一个字符串input="maybe(thisis|thatwas)some((nice|ugly)(day|night)|(strange(weather|time)))"Ruby中解析该字符串的最佳方法是什么?我的意思是脚本应该能够像这样构建句子:maybethisissomeuglynightmaybethatwassomenicenightmaybethiswassomestrangetime等等,你明白了......我应该一个字符一个字符地读取字符串并构建一个带有堆栈的状态机来存储括号值以供以后计算,还是有更好的方法?也许为此目的准备了一个开箱即用的库?

  2. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  3. ruby - 用逗号、双引号和编码解析 csv - 2

    我正在使用ruby​​1.9解析以下带有MacRoman字符的csv文件#encoding:ISO-8859-1#csv_parse.csvName,main-dialogue"Marceu","Giveittohimóhe,hiswife."我做了以下解析。require'csv'input_string=File.read("../csv_parse.rb").force_encoding("ISO-8859-1").encode("UTF-8")#=>"Name,main-dialogue\r\n\"Marceu\",\"Giveittohim\x97he,hiswife.\"\

  4. ruby - 如何模拟 Net::HTTP::Post? - 2

    是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou

  5. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  6. ruby-on-rails - 我更新了 ruby​​ gems,现在到处都收到解析树错误和弃用警告! - 2

    简而言之错误:NOTE:Gem::SourceIndex#add_specisdeprecated,useSpecification.add_spec.Itwillberemovedonorafter2011-11-01.Gem::SourceIndex#add_speccalledfrom/opt/local/lib/ruby/site_ruby/1.8/rubygems/source_index.rb:91./opt/local/lib/ruby/gems/1.8/gems/rails-2.3.8/lib/rails/gem_dependency.rb:275:in`==':und

  7. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

  8. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  9. MIMO-OFDM无线通信技术及MATLAB实现(1)无线信道:传播和衰落 - 2

     MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO

  10. 在VMware16虚拟机安装Ubuntu详细教程 - 2

    在VMware16.2.4安装Ubuntu一、安装VMware1.打开VMwareWorkstationPro官网,点击即可进入。2.进入后向下滑动找到Workstation16ProforWindows,点击立即下载。3.下载完成,文件大小615MB,如下图:4.鼠标右击,以管理员身份运行。5.点击下一步6.勾选条款,点击下一步7.先勾选,再点击下一步8.去掉勾选,点击下一步9.点击下一步10.点击安装11.点击许可证12.在百度上搜索VM16许可证,复制填入,然后点击输入即可,亲测有效。13.点击完成14.重启系统,点击是15.双击VMwareWorkstationPro图标,进入虚拟机主

随机推荐