• 一些常见函数的内部实现(原)


    一些常见函数的内部实现(原)

    Wentao Sun

    1. 子串查找:

    /* strtok_s */
    /*
     * strtok_s, wcstok_s ;
     * uses _Context to keep track of the position in the string.
     
    */
    _SAFECRT__EXTERN_C
    char * __cdecl strtok_s(char *_String, const char *_Control, char **_Context);

    #if _SAFECRT_USE_INLINES

    __inline
    char * __cdecl strtok_s(char *_String, const char *_Control, char **_Context)
    {
        unsigned 
    char *str;
        
    const unsigned char *ctl = (const unsigned char *)_Control;
        unsigned 
    char map[32];
        
    int count;

        
    /* validation section */
        _SAFECRT__VALIDATE_POINTER_ERROR_RETURN(_Context, EINVAL, NULL);
        _SAFECRT__VALIDATE_POINTER_ERROR_RETURN(_Control, EINVAL, NULL);
        _SAFECRT__VALIDATE_CONDITION_ERROR_RETURN(_String != NULL || *_Context != NULL, EINVAL, NULL);

        /* Clear control map */
        
    for (count = 0; count < 32; count++)
        {
            map[count] 
    = 0;
        }

        
    /* Set bits in delimiter table */
        
    do {
            map[
    *ctl >> 3|= (1 << (*ctl & 7));
        } 
    while (*ctl++);

        
    /* If string is NULL, set str to the saved
        * pointer (i.e., continue breaking tokens out of the string
        * from the last strtok call) 
    */
        
    if (_String != NULL)
        {
            str 
    = (unsigned char *)_String;
        }
        
    else
        {
            str 
    = (unsigned char *)*_Context;
        }

        
    /* Find beginning of token (skip over leading delimiters). Note that
        * there is no token iff this loop sets str to point to the terminal
        * null (*str == 0) 
    */
        
    while ((map[*str >> 3& (1 << (*str & 7))) && *str != 0)
        {
            str
    ++;
        }

        _String 
    = (char *)str;

        
    /* Find the end of the token. If it is not the end of the string,
        * put a null there. 
    */
        
    for ( ; *str != 0 ; str++ )
        {
            
    if (map[*str >> 3& (1 << (*str & 7)))
            {
                
    *str++ = 0;
                
    break;
            }
        }

        
    /* Update context */
        
    *_Context = (char *)str;

        
    /* Determine if a token has been found. */
        
    if (_String == (char *)str)
        {
            
    return NULL;
        }
        
    else
        {
            
    return _String;
        }
    }
    #endif

    /* wcstok_s */
    _SAFECRT__EXTERN_C
    wchar_t 
    * __cdecl wcstok_s(wchar_t *_String, const wchar_t *_Control, wchar_t **_Context);

    #if _SAFECRT_USE_INLINES

    __inline
    wchar_t 
    * __cdecl wcstok_s(wchar_t *_String, const wchar_t *_Control, wchar_t **_Context)
    {
        wchar_t 
    *token;
        
    const wchar_t *ctl;

        
    /* validation section */
        _SAFECRT__VALIDATE_POINTER_ERROR_RETURN(_Context, EINVAL, NULL);
        _SAFECRT__VALIDATE_POINTER_ERROR_RETURN(_Control, EINVAL, NULL);
        _SAFECRT__VALIDATE_CONDITION_ERROR_RETURN(_String != NULL || *_Context != NULL, EINVAL, NULL);


        
    /* If string==NULL, continue with previous string */
        
    if (!_String)
        {
            _String 
    = *_Context;
        }

        
    /* Find beginning of token (skip over leading delimiters). Note that
        * there is no token iff this loop sets string to point to the terminal null. 
    */
        
    for ( ; *_String != 0 ; _String++)
        {
            
    for (ctl = _Control; *ctl != 0 && *ctl != *_String; ctl++)
                ;
            
    if (*ctl == 0)
            {
                
    break;
            }
        }

        token 
    = _String;

        
    /* Find the end of the token. If it is not the end of the string,
        * put a null there. 
    */
        
    for ( ; *_String != 0 ; _String++)
        {
            
    for (ctl = _Control; *ctl != 0 && *ctl != *_String; ctl++)
                ;
            
    if (*ctl != 0)
            {
                
    *_String++ = 0;
                
    break;
            }
        }

        
    /* Update the context */
        
    *_Context = _String;

        
    /* Determine if a token has been found. */
        
    if (token == _String)
        {
            
    return NULL;
        }
        
    else
        {
            
    return token;
        }
    }
    #endif

     

     2. 使用strsafe.h时需要注意将其放到其他string操作头文件的后面,以免不必要的编译错误。

    可以参考:http://www.programfan.com/club/showtxt.asp?id=235904
    我今天在编译的适合也碰到过这个问题。

    再次强调,使用strsafe.h最好是放在cpp文件中,而非头文件中。

    在微软的tchar.h中明确的有个#error put strsafe.h behind thar.h。 strsafe.h被要求放在tchar.h的后面。如果不这样,会得到一堆很奇怪的错误。

     

     

  • 相关阅读:
    给定圆心和半径在圆内随机画点
    mqtt使用二(集成到java代码中)
    mqtt使用一
    vue的细节
    mongodb学习一(使用mongoResposity)
    jadx-gui for Mac
    对xx面APP进行分析
    使用jeb对某圈进行协议分析
    proxifier 安卓模拟器设置全局代理fq
    安卓开启真机调试ro.debuggable 1修改ro属性
  • 原文地址:https://www.cnblogs.com/SunWentao/p/1300037.html
Copyright © 2020-2023  润新知