• strtok(), strtok_s() 字符串分割函数


     //strtok()函数原型
     /*_Check_return_ _CRT_INSECURE_DEPRECATE(strtok_s) _CRTIMP 
                          char *  __cdecl strtok(_Inout_opt_z_ char * _Str, _In_z_ const char * _Delim);*/


    当strtok()在参数_Str的字符串中发现参数_Delim中包涵的分割字符时,则会将该字符改为 字符。

    在第一次调用时,strtok()必需给予参数_Str字符串,往后的调用则将参数_Str设置成NULL。每次调用成功则返回指向被分割出片段的指针。

    需要注意的是,使用该函数进行字符串分割时,会破坏被分解字符串的完整,调用前和调用后的s已经不一样了。

    第一次分割之后,原字符串str是分割完成之后的第一个字符串,剩余的字符串存储在一个静态变量中。

    //将字符串"ab,cde,fghi"按照","分割。
    char
    str[] = "ab,cde,fghi"; char *p[4]; p[0]= strtok(str, ","); int i = 0; while (p[i] != NULL) { i++; p[i]= strtok(NULL, ","); } p[i] = ""; for (int i = 0; i < 4; i++) { cout << p[i] << endl; }

    //strtok_s()函数原型
    /*_Check_return_ _CRTIMP_ALTERNATIVE 
        char *  __cdecl strtok_s(_Inout_opt_z_ char * _Str, _In_z_ const char * _Delim, _Inout_ _Deref_prepost_opt_z_ char ** _Context);*/

    仍然会破坏原字符串的完整性。但是函数将剩余的字符串存储在_Context变量中,而不是静态变量中,从而保证了安全性。

    char ** _Context参数是一个指向char *的指针变量,用来在strtok_s内部保存切分时的上下文,以应对连续调用分解相同源字符串。 

    strtok函数在提取字符串时使用了静态缓冲区,因此,线程不安全。如果要顾及到线程的安全性,应该使用strtok_s。

    strtok_s实际上就是将strtok内部隐式保存的this指针,以参数的形式与函数外部进行交互。由调用者进行传递、保存甚至是修改。

    需要调用者在连续切分相同源字符串时,除了将str参数赋值为NULL,还要传递上次切分时保存下的_Context

    //将字符串"hello world,my name is congcong."按照","分割。
    char
    str[] = "hello world,my name is congcong."; char *p[3]; char *buf; p[0]=strtok_s(str, ",",&buf); int i = 0; while (p[i]) { i++; p[i] = strtok_s(NULL, ",", &buf); } p[i] = ""; for (int i = 0; i < 3; i++) { cout << p[i] << endl; }

     连续调用分解相同源字符串时,strtok_s()函数更加直观的体现了其便捷性。

    //将字符串"hello world,my name is congcong."按照","和" "分割。
    //先按","分割,在每个字串里面按照" "分割。双重循环过程中,需记录出剩下的串。

    char
    str[] = "hello world,my name is congcong."; char *p[8]; char *buf; char *buftmp; char *strtmp = new char[strlen(str)+1]; strcpy(strtmp, str); //p[0] = strtok_s(strtmp, ",", &buf); int i = 0; while (p[i] = strtok_s(strtmp, ",", &buf)) { strtmp = p[i]; //p[i] = strtok_s(strtmp, " ", &buftmp); while (p[i] = strtok_s(strtmp, " ", &buftmp)) { i++; //p[i] = strtok_s(NULL, " ", &buftmp); strtmp = NULL; } //p[i] = strtok_s(NULL, ",", &buf); strtmp = NULL; } //p[i] = ""; for (int j = 0; j < i; j++) { cout << p[j] << endl; }

    
    
    
    
    
  • 相关阅读:
    TP5 查询mysql数据库时的find_in_set用法
    使用paginate方法分页无法判断获取的数据是否为空
    苹果电脑Mac系统如何安装Adobe Flash Player
    JavaScript Timing 事件及两种时钟写法
    JavaScript 弹出框
    JavaScript 表单验证
    fastadmin CMS等系列插件安装不成功的问题
    fastadmin中js是如何调用的
    fastadmin安装定时插件报错 ZipArchive::extractTo(): Permission denied
    今天科普一下 苹果开发者账号中:个人、公司、企业账号的区别
  • 原文地址:https://www.cnblogs.com/zhoudingcocng/p/6554418.html
Copyright © 2020-2023  润新知