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

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

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的后面。如果不这样,会得到一堆很奇怪的错误。

 

 

你可能感兴趣的:(函数)