zoukankan      html  css  js  c++  java
  • 字符串操作函数<string.h>相关函数strcpy,strcat,等源码。

    首先说一下源码到底在哪里找。

    我们在文件中包含<cstring>时,如果点击右键打开文档,

    会打开cstring,我们会发现路径为:

    D:Program Filesvisual studioVCincludecstring

    这个文件内容如下:

    // cstring standard header
    #pragma once
    #ifndef _CSTRING_
    #define _CSTRING_
    #include <yvals.h>
    
    #ifdef _STD_USING
     #undef _STD_USING
      #include <string.h>
     #define _STD_USING
    
    #else /* _STD_USING */
     #include <string.h>
    #endif /* _STD_USING */
    
     #if _GLOBAL_USING && !defined(RC_INVOKED)
    _STD_BEGIN
    using _CSTD size_t; using _CSTD memchr; using _CSTD memcmp;
    
    using _CSTD memcpy; using _CSTD memmove; using _CSTD memset;
    using _CSTD strcat; using _CSTD strchr; using _CSTD strcmp;
    using _CSTD strcoll; using _CSTD strcpy; using _CSTD strcspn;
    using _CSTD strerror; using _CSTD strlen; using _CSTD strncat;
    using _CSTD strncmp; using _CSTD strncpy; using _CSTD strpbrk;
    using _CSTD strrchr; using _CSTD strspn; using _CSTD strstr;
    using _CSTD strtok; using _CSTD strxfrm;
    _STD_END
     #endif /* _GLOBAL_USING */
    
    #endif /* _CSTRING_ */
    
    /*
     * Copyright (c) 1992-2009 by P.J. Plauger.  ALL RIGHTS RESERVED.
     * Consult your license regarding permissions and restrictions.
    V5.20:0009 */

    它没有cpp文件。包含了<string.h>头文件,也在这个目录下,内容如下;

    /***
    *string.h - declarations for string manipulation functions
    *
    *       Copyright (c) Microsoft Corporation. All rights reserved.
    *
    *Purpose:
    *       This file contains the function declarations for the string
    *       manipulation functions.
    *       [ANSI/System V]
    *
    *       [Public]
    *
    ****/
    
    #pragma once
    
    #ifndef _INC_STRING
    #define _INC_STRING
    
    #include <crtdefs.h>
    
    #ifdef  __cplusplus
    extern "C" {
    #endif
    
    #ifndef _NLSCMP_DEFINED
    #define _NLSCMPERROR    2147483647  /* currently == INT_MAX */
    #define _NLSCMP_DEFINED
    #endif
    
    /* Define NULL pointer value */
    #ifndef NULL
    #ifdef __cplusplus
    #define NULL    0
    #else
    #define NULL    ((void *)0)
    #endif
    #endif
    
    /* For backwards compatibility */
    #define _WConst_return _CONST_RETURN
    
    /* Function prototypes */
    #ifndef _CRT_MEMORY_DEFINED
    #define _CRT_MEMORY_DEFINED
    _CRTIMP void *  __cdecl _memccpy( _Out_opt_bytecap_(_MaxCount) void * _Dst, _In_ const void * _Src, _In_ int _Val, _In_ size_t _MaxCount);
    _Check_return_ _CRTIMP _CONST_RETURN void *  __cdecl memchr( _In_opt_bytecount_(_MaxCount) const void * _Buf , _In_ int _Val, _In_ size_t _MaxCount);
    _Check_return_ _CRTIMP int     __cdecl _memicmp(_In_opt_bytecount_(_Size) const void * _Buf1, _In_opt_bytecount_(_Size) const void * _Buf2, _In_ size_t _Size);
    _Check_return_ _CRTIMP int     __cdecl _memicmp_l(_In_opt_bytecount_(_Size) const void * _Buf1, _In_opt_bytecount_(_Size) const void * _Buf2, _In_ size_t _Size, _In_opt_ _locale_t _Locale);
            _Check_return_ int     __cdecl memcmp(_In_opt_bytecount_(_Size) const void * _Buf1, _In_opt_bytecount_(_Size) const void * _Buf2, _In_ size_t _Size);
            _CRT_INSECURE_DEPRECATE_MEMORY(memcpy_s) void *  __cdecl memcpy(_Out_opt_bytecapcount_(_Size) void * _Dst, _In_opt_bytecount_(_Size) const void * _Src, _In_ size_t _Size);
    #if __STDC_WANT_SECURE_LIB__
    _CRTIMP errno_t  __cdecl memcpy_s(_Out_opt_bytecap_post_bytecount_(_DstSize, _MaxCount) void * _Dst, _In_ rsize_t _DstSize, _In_opt_bytecount_(_MaxCount) const void * _Src, _In_ rsize_t _MaxCount);
    #if defined(__cplusplus) && _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_MEMORY
    extern "C++"
    {
     #ifndef _CRT_ENABLE_IF_DEFINED
      #define _CRT_ENABLE_IF_DEFINED
        template<bool _Enable, typename _Ty>
        struct _CrtEnableIf;
    
        template<typename _Ty>
        struct _CrtEnableIf<true, _Ty>
        {
            typedef _Ty _Type;
        };
     #endif
        template <size_t _Size, typename _DstType>
        inline
        typename _CrtEnableIf<(_Size > 1), void *>::_Type __cdecl memcpy(_DstType (&_Dst)[_Size], _In_opt_bytecount_(_SrcSize) const void *_Src, _In_ size_t _SrcSize) _CRT_SECURE_CPP_NOTHROW
        {
            return memcpy_s(_Dst, _Size * sizeof(_DstType), _Src, _SrcSize) == 0 ? _Dst : 0;
        }
    }
    #endif
    #if defined(__cplusplus) && _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES_MEMORY
    extern "C++"
    {
        template <size_t _Size, typename _DstType>
        inline
        errno_t __CRTDECL memcpy_s(_DstType (&_Dst)[_Size], _In_opt_bytecount_(_SrcSize) const void * _Src, _In_ rsize_t _SrcSize) _CRT_SECURE_CPP_NOTHROW
        {
            return memcpy_s(_Dst, _Size * sizeof(_DstType), _Src, _SrcSize);
        }
    }
    #endif
    #endif
            void *  __cdecl memset(_Out_opt_bytecapcount_(_Size) void * _Dst, _In_ int _Val, _In_ size_t _Size);
    
    #if     !__STDC__
    /* Non-ANSI names for compatibility */
    _CRT_NONSTDC_DEPRECATE(_memccpy) _CRTIMP void * __cdecl memccpy(_Out_opt_bytecap_(_Size) void * _Dst, _In_opt_bytecount_(_Size) const void * _Src, _In_ int _Val, _In_ size_t _Size);
    _Check_return_ _CRT_NONSTDC_DEPRECATE(_memicmp) _CRTIMP int __cdecl memicmp(_In_opt_bytecount_(_Size) const void * _Buf1, _In_opt_bytecount_(_Size) const void * _Buf2, _In_ size_t _Size);
    #endif  /* __STDC__ */
    
    #endif
    
    _Check_return_wat_ _CRTIMP_ALTERNATIVE errno_t __cdecl _strset_s(_Inout_z_cap_(_DstSize) char * _Dst, _In_ size_t _DstSize, _In_ int _Value);
    __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1(errno_t, _strset_s, _Deref_prepost_z_ char, _Dest, _In_ int, _Value)
    __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1(char *, __RETURN_POLICY_DST, __EMPTY_DECLSPEC, _strset, _Inout_z_, char, _Dest, _In_ int, _Value)
    #if __STDC_WANT_SECURE_LIB__
    _Check_return_wat_ _CRTIMP_ALTERNATIVE errno_t __cdecl strcpy_s(_Out_z_cap_(_SizeInBytes) char * _Dst, _In_ rsize_t _SizeInBytes, _In_z_ const char * _Src);
    #endif
    __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1(errno_t, strcpy_s, _Deref_post_z_ char, _Dest, _In_z_ const char *, _Source)
    __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1(char *, __RETURN_POLICY_DST, __EMPTY_DECLSPEC, strcpy, _Pre_cap_for_(_Source) _Post_z_, char, _Dest, _In_z_ const char *, _Source)
    #if __STDC_WANT_SECURE_LIB__
    _Check_return_wat_ _CRTIMP_ALTERNATIVE errno_t __cdecl strcat_s(_Inout_z_cap_(_SizeInBytes) char * _Dst, _In_ rsize_t _SizeInBytes, _In_z_ const char * _Src);
    #endif
    __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1(errno_t, strcat_s, _Deref_prepost_z_ char, _Dest, _In_z_ const char *, _Source)
    __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1(char *, __RETURN_POLICY_DST, __EMPTY_DECLSPEC, strcat, _Pre_cap_for_(_Source) _Prepost_z_, char, _Dest, _In_z_ const char *, _Source)
            _Check_return_ int     __cdecl strcmp(_In_z_ const char * _Str1, _In_z_ const char * _Str2);
            _Check_return_ size_t  __cdecl strlen(_In_z_ const char * _Str);
    _Check_return_ _CRTIMP size_t  __cdecl strnlen(_In_z_ const char * _Str, _In_ size_t _MaxCount);
    #if __STDC_WANT_SECURE_LIB__ && !defined (__midl)
    _Check_return_ static __inline size_t  __CRTDECL strnlen_s(_In_z_  const char * _Str, _In_ size_t _MaxCount)
    {
        return (_Str==0) ? 0 : strnlen(_Str, _MaxCount);
    }
    #endif
    #if __STDC_WANT_SECURE_LIB__
    _Check_return_wat_ _CRTIMP errno_t __cdecl memmove_s(_Out_opt_bytecap_post_bytecount_(_DstSize,_MaxCount) void * _Dst, _In_ rsize_t _DstSize, _In_opt_bytecount_(_MaxCount) const void * _Src, _In_ rsize_t _MaxCount);
    #endif
    
    #if     defined(_M_IA64)
            _CRT_INSECURE_DEPRECATE_MEMORY(memmove_s) void *  __cdecl memmove(_Out_opt_bytecapcount_(_Size) void * _Dst, _In_opt_bytecount_(_Size) const void * _Src, _In_ size_t _Size);
    #else  /* defined (_M_IA64) */
    _CRTIMP _CRT_INSECURE_DEPRECATE_MEMORY(memmove_s) void *  __cdecl memmove(_Out_opt_bytecapcount_(_Size) void * _Dst, _In_opt_bytecount_(_Size) const void * _Src, _In_ size_t _Size);
    #endif  /* defined (_M_IA64) */
    
    #if defined(_DEBUG) && defined(_CRTDBG_MAP_ALLOC)
    #pragma push_macro("_strdup")
    #undef _strdup
    #endif
    
    _Check_return_ _CRTIMP char *  __cdecl _strdup(_In_opt_z_ const char * _Src);
    
    #if defined(_DEBUG) && defined(_CRTDBG_MAP_ALLOC)
    #pragma pop_macro("_strdup")
    #endif
    
    _Check_return_ _CRTIMP _CONST_RETURN char *  __cdecl strchr(_In_z_ const char * _Str, _In_ int _Val);
    _Check_return_ _CRTIMP int     __cdecl _stricmp(_In_z_  const char * _Str1, _In_z_  const char * _Str2);
    _Check_return_ _CRTIMP int     __cdecl _strcmpi(_In_z_  const char * _Str1, _In_z_  const char * _Str2);
    _Check_return_ _CRTIMP int     __cdecl _stricmp_l(_In_z_  const char * _Str1, _In_z_  const char * _Str2, _In_opt_ _locale_t _Locale);
    _Check_return_ _CRTIMP int     __cdecl strcoll(_In_z_  const char * _Str1, _In_z_  const  char * _Str2);
    _Check_return_ _CRTIMP int     __cdecl _strcoll_l(_In_z_  const char * _Str1, _In_z_  const char * _Str2, _In_opt_ _locale_t _Locale);
    _Check_return_ _CRTIMP int     __cdecl _stricoll(_In_z_  const char * _Str1, _In_z_  const char * _Str2);
    _Check_return_ _CRTIMP int     __cdecl _stricoll_l(_In_z_  const char * _Str1, _In_z_  const char * _Str2, _In_opt_ _locale_t _Locale);
    _Check_return_ _CRTIMP int     __cdecl _strncoll  (_In_z_ const char * _Str1, _In_z_ const char * _Str2, _In_ size_t _MaxCount);
    _Check_return_ _CRTIMP int     __cdecl _strncoll_l(_In_z_ const char * _Str1, _In_z_ const char * _Str2, _In_ size_t _MaxCount, _In_opt_ _locale_t _Locale);
    _Check_return_ _CRTIMP int     __cdecl _strnicoll (_In_z_ const char * _Str1, _In_z_ const char * _Str2, _In_ size_t _MaxCount);
    _Check_return_ _CRTIMP int     __cdecl _strnicoll_l(_In_z_ const char * _Str1, _In_z_ const char * _Str2, _In_ size_t _MaxCount, _In_opt_ _locale_t _Locale);
    _Check_return_ _CRTIMP size_t  __cdecl strcspn(_In_z_  const char * _Str, _In_z_  const char * _Control);
    _Check_return_ _CRT_INSECURE_DEPRECATE(_strerror_s) _CRTIMP char *  __cdecl _strerror(_In_opt_z_ const char * _ErrMsg);
    _Check_return_wat_ _CRTIMP errno_t __cdecl _strerror_s(_Out_z_cap_(_SizeInBytes) char * _Buf, _In_ size_t _SizeInBytes, _In_opt_z_ const char * _ErrMsg);
    __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1(errno_t, _strerror_s, char, _Buffer, _In_opt_z_ const char *, _ErrorMessage)
    _Check_return_ _CRT_INSECURE_DEPRECATE(strerror_s) _CRTIMP char *  __cdecl strerror(_In_ int);
    #if __STDC_WANT_SECURE_LIB__
    _Check_return_wat_ _CRTIMP errno_t __cdecl strerror_s(_Out_z_cap_(_SizeInBytes) char * _Buf, _In_ size_t _SizeInBytes, _In_ int _ErrNum);
    #endif
    __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1(errno_t, strerror_s, char, _Buffer, _In_ int, _ErrorMessage)
    _Check_return_wat_ _CRTIMP errno_t __cdecl _strlwr_s(_Inout_z_cap_(_Size) char * _Str, _In_ size_t _Size);
    __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_0(errno_t, _strlwr_s, _Deref_prepost_z_ char, _String)
    __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_0(char *, __RETURN_POLICY_DST, _CRTIMP, _strlwr, _Inout_z_, char, _String)
    _Check_return_wat_ _CRTIMP errno_t __cdecl _strlwr_s_l(_Inout_z_cap_(_Size) char * _Str, _In_ size_t _Size, _In_opt_ _locale_t _Locale);
    __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1(errno_t, _strlwr_s_l, _Deref_prepost_z_ char, _String, _In_opt_ _locale_t, _Locale)
    __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1_EX(char *, __RETURN_POLICY_DST, _CRTIMP, _strlwr_l, _strlwr_s_l, _Deref_inout_z_cap_c_(_Size) char, _Inout_z_, char, _String, _In_opt_ _locale_t, _Locale)
    #if __STDC_WANT_SECURE_LIB__
    _Check_return_wat_ _CRTIMP_ALTERNATIVE errno_t __cdecl strncat_s(_Inout_z_cap_(_SizeInBytes) char * _Dst, _In_ rsize_t _SizeInBytes, _In_z_ const char * _Src, _In_ rsize_t _MaxCount);
    #endif
    __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2(errno_t, strncat_s, _Deref_prepost_z_ char, _Dest, _In_z_ const char *, _Source, _In_ size_t, _Count)
    #pragma warning(push)
    #pragma warning(disable:6059)
    /* prefast noise VSW 489802 */
    __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_EX(char *, __RETURN_POLICY_DST, _CRTIMP, strncat, strncat_s, _Deref_inout_z_cap_c_(_Size) char, _Inout_z_cap_(_Count), char, _Dest, _In_z_ const char *, _Source, _In_ size_t, _Count)
    #pragma warning(pop)
    #if     defined(_M_IA64)
            _Check_return_ int     __cdecl strncmp(_In_z_  const char * _Str1, _In_z_ const char * _Str2, _In_ size_t _MaxCount);
    #else
    _Check_return_ _CRTIMP int     __cdecl strncmp(_In_z_ const char * _Str1, _In_z_ const char * _Str2, _In_ size_t _MaxCount);
    #endif
    _Check_return_ _CRTIMP int     __cdecl _strnicmp(_In_z_ const char * _Str1, _In_z_ const char * _Str2, _In_ size_t _MaxCount);
    _Check_return_ _CRTIMP int     __cdecl _strnicmp_l(_In_z_ const char * _Str1, _In_z_ const char * _Str2, _In_ size_t _MaxCount, _In_opt_ _locale_t _Locale);
    #if __STDC_WANT_SECURE_LIB__
    _Check_return_wat_ _CRTIMP_ALTERNATIVE errno_t __cdecl strncpy_s(_Out_z_cap_(_SizeInBytes) char * _Dst, _In_ rsize_t _SizeInBytes, _In_z_ const char * _Src, _In_ rsize_t _MaxCount);
    #endif
    __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2(errno_t, strncpy_s, char, _Dest, _In_z_ const char *, _Source, _In_ size_t, _Count)
    __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_EX(char *, __RETURN_POLICY_DST, _CRTIMP_NOIA64, strncpy, strncpy_s, _Deref_out_z_cap_c_(_Size) char, _Out_cap_(_Count) _Post_maybez_, char, _Dest, _In_z_ const char *, _Source, _In_ size_t, _Count)
    _Check_return_wat_ _CRTIMP_ALTERNATIVE errno_t __cdecl _strnset_s(_Inout_z_cap_(_SizeInBytes) char * _Str, _In_ size_t _SizeInBytes, _In_ int _Val, _In_ size_t _MaxCount);
    __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2(errno_t, _strnset_s, _Deref_prepost_z_ char, _Dest, _In_ int, _Val, _In_ size_t, _Count)
    __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_EX(char *, __RETURN_POLICY_DST, _CRTIMP, _strnset, _strnset_s, _Deref_inout_z_cap_c_(_Size) char, _Inout_z_cap_(_Count), char, _Dest, _In_ int, _Val, _In_ size_t, _Count)
    _Check_return_ _CRTIMP _CONST_RETURN char *  __cdecl strpbrk(_In_z_ const char * _Str, _In_z_ const char * _Control);
    _Check_return_ _CRTIMP _CONST_RETURN char *  __cdecl strrchr(_In_z_ const char * _Str, _In_ int _Ch);
    _CRTIMP char *  __cdecl _strrev(_Inout_z_ char * _Str);
    _Check_return_ _CRTIMP size_t  __cdecl strspn(_In_z_ const char * _Str, _In_z_ const char * _Control);
    _Check_return_ _CRTIMP _CONST_RETURN char *  __cdecl strstr(_In_z_ const char * _Str, _In_z_ const char * _SubStr);
    _Check_return_ _CRT_INSECURE_DEPRECATE(strtok_s) _CRTIMP char *  __cdecl strtok(_Inout_opt_z_ char * _Str, _In_z_ const char * _Delim);
    #if __STDC_WANT_SECURE_LIB__
    _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);
    #endif
    _Check_return_wat_ _CRTIMP errno_t __cdecl _strupr_s(_Inout_z_cap_(_Size) char * _Str, _In_ size_t _Size);
    __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_0(errno_t, _strupr_s, _Deref_prepost_z_ char, _String)
    __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_0(char *, __RETURN_POLICY_DST, _CRTIMP, _strupr, _Inout_z_, char, _String)
    _Check_return_wat_ _CRTIMP errno_t __cdecl _strupr_s_l(_Inout_z_cap_(_Size) char * _Str, _In_ size_t _Size, _locale_t _Locale);
    __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1(errno_t, _strupr_s_l, _Deref_prepost_z_ char, _String, _locale_t, _Locale)
    __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1_EX(char *, __RETURN_POLICY_DST, _CRTIMP, _strupr_l, _strupr_s_l, _Deref_inout_z_cap_c_(_Size) char, _Inout_z_, char, _String, _In_opt_ _locale_t, _Locale)
    _Check_return_opt_ _CRTIMP size_t  __cdecl strxfrm (_Out_opt_cap_(_MaxCount) _Post_maybez_ char * _Dst, _In_z_ const char * _Src, _In_ size_t _MaxCount);
    _Check_return_opt_ _CRTIMP size_t  __cdecl _strxfrm_l(_Out_opt_cap_(_MaxCount) _Post_maybez_ char * _Dst, _In_z_ const char * _Src, _In_ size_t _MaxCount, _In_opt_ _locale_t _Locale);
    
    #ifdef __cplusplus
    extern "C++" {
    #ifndef _CPP_NARROW_INLINES_DEFINED
    #define _CPP_NARROW_INLINES_DEFINED
    _Check_return_ inline char * __CRTDECL strchr(_In_z_ char * _Str, _In_ int _Ch)
        { return (char*)strchr((const char*)_Str, _Ch); }
    _Check_return_ inline char * __CRTDECL strpbrk(_In_z_ char * _Str, _In_z_ const char * _Control)
        { return (char*)strpbrk((const char*)_Str, _Control); }
    _Check_return_ inline char * __CRTDECL strrchr(_In_z_ char * _Str, _In_ int _Ch)
        { return (char*)strrchr((const char*)_Str, _Ch); }
    _Check_return_ inline char * __CRTDECL strstr(_In_z_ char * _Str, _In_z_ const char * _SubStr)
        { return (char*)strstr((const char*)_Str, _SubStr); }
    #endif
    #ifndef _CPP_MEMCHR_DEFINED
    #define _CPP_MEMCHR_DEFINED
    _Check_return_ inline void * __CRTDECL memchr(_In_opt_bytecount_(_N) void * _Pv, _In_ int _C, _In_ size_t _N)
        { return (void*)memchr((const void*)_Pv, _C, _N); }
    #endif
    }
    #endif
    
    #if     !__STDC__
    
    #if defined(_DEBUG) && defined(_CRTDBG_MAP_ALLOC)
    #pragma push_macro("strdup")
    #undef strdup
    #endif
    
    _Check_return_ _CRT_NONSTDC_DEPRECATE(_strdup) _CRTIMP char * __cdecl strdup(_In_opt_z_ const char * _Src);
    
    #if defined(_DEBUG) && defined(_CRTDBG_MAP_ALLOC)
    #pragma pop_macro("strdup")
    #endif
    
    /* prototypes for oldnames.lib functions */
    _Check_return_ _CRT_NONSTDC_DEPRECATE(_strcmpi) _CRTIMP int __cdecl strcmpi(_In_z_ const char * _Str1, _In_z_ const char * _Str2);
    _Check_return_ _CRT_NONSTDC_DEPRECATE(_stricmp) _CRTIMP int __cdecl stricmp(_In_z_ const char * _Str1, _In_z_ const char * _Str2);
    _CRT_NONSTDC_DEPRECATE(_strlwr) _CRTIMP char * __cdecl strlwr(_Inout_z_ char * _Str);
    _Check_return_ _CRT_NONSTDC_DEPRECATE(_strnicmp) _CRTIMP int __cdecl strnicmp(_In_z_ const char * _Str1, _In_z_ const char * _Str, _In_ size_t _MaxCount);
    _CRT_NONSTDC_DEPRECATE(_strnset) _CRTIMP char * __cdecl strnset(_Inout_z_cap_(_MaxCount) char * _Str, _In_ int _Val, _In_ size_t _MaxCount);
    _CRT_NONSTDC_DEPRECATE(_strrev) _CRTIMP char * __cdecl strrev(_Inout_z_ char * _Str);
    _CRT_NONSTDC_DEPRECATE(_strset)         char * __cdecl strset(_Inout_z_ char * _Str, _In_ int _Val);
    _CRT_NONSTDC_DEPRECATE(_strupr) _CRTIMP char * __cdecl strupr(_Inout_z_ char * _Str);
    
    #endif  /* !__STDC__ */
    
    
    #ifndef _WSTRING_DEFINED
    
    /* wide function prototypes, also declared in wchar.h  */
    
    #if defined(_DEBUG) && defined(_CRTDBG_MAP_ALLOC)
    #pragma push_macro("_wcsdup")
    #undef _wcsdup
    #endif
    
    _Check_return_ _CRTIMP wchar_t * __cdecl _wcsdup(_In_z_ const wchar_t * _Str);
    
    #if defined(_DEBUG) && defined(_CRTDBG_MAP_ALLOC)
    #pragma pop_macro("_wcsdup")
    #endif
    
    #if __STDC_WANT_SECURE_LIB__
    _Check_return_wat_ _CRTIMP_ALTERNATIVE errno_t __cdecl wcscat_s(_Inout_z_cap_(_SizeInWords) wchar_t * _Dst, _In_ rsize_t _SizeInWords, _In_z_ const wchar_t * _Src);
    #endif
    __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1(errno_t, wcscat_s, _Deref_prepost_z_ wchar_t, _Dest, _In_z_ const wchar_t *, _Source)
    __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1(wchar_t *, __RETURN_POLICY_DST, _CRTIMP, wcscat, _Pre_cap_for_(_Source) _Prepost_z_, wchar_t, _Dest, _In_z_ const wchar_t *, _Source)
    _Check_return_ _CRTIMP _CONST_RETURN wchar_t * __cdecl wcschr(_In_z_ const wchar_t * _Str, wchar_t _Ch);
    _Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t * _Str1, _In_z_ const wchar_t * _Str2);
    #if __STDC_WANT_SECURE_LIB__
    _Check_return_wat_ _CRTIMP_ALTERNATIVE errno_t __cdecl wcscpy_s(_Out_z_cap_(_SizeInWords) wchar_t * _Dst, _In_ rsize_t _SizeInWords, _In_z_ const wchar_t * _Src);
    #endif
    __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1(errno_t, wcscpy_s, wchar_t, _Dest, _In_z_ const wchar_t *, _Source)
    __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1(wchar_t *, __RETURN_POLICY_DST, _CRTIMP, wcscpy, _Pre_cap_for_(_Source) _Post_z_, wchar_t, _Dest, _In_z_ const wchar_t *, _Source)
    _Check_return_ _CRTIMP size_t __cdecl wcscspn(_In_z_ const wchar_t * _Str, _In_z_ const wchar_t * _Control);
    _Check_return_ _CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t * _Str);
    _Check_return_ _CRTIMP size_t __cdecl wcsnlen(_In_z_ const wchar_t * _Src, _In_ size_t _MaxCount);
    #if __STDC_WANT_SECURE_LIB__ && !defined (__midl)
    _Check_return_ static __inline size_t __CRTDECL wcsnlen_s(_In_z_ const wchar_t * _Src, _In_ size_t _MaxCount)
    {
        return (_Src == NULL) ? 0 : wcsnlen(_Src, _MaxCount);
    }
    #endif
    #if __STDC_WANT_SECURE_LIB__
    _Check_return_wat_ _CRTIMP_ALTERNATIVE errno_t __cdecl wcsncat_s(_Inout_z_cap_(_SizeInWords) wchar_t * _Dst, _In_ rsize_t _SizeInWords, _In_z_ const wchar_t * _Src, _In_ rsize_t _MaxCount);
    #endif
    __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2(errno_t, wcsncat_s, _Deref_prepost_z_ wchar_t, _Dest, _In_z_ const wchar_t *, _Source, _In_ size_t, _Count)
    #pragma warning(push)
    #pragma warning(disable:6059)
    __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_EX(wchar_t *, __RETURN_POLICY_DST, _CRTIMP, wcsncat, wcsncat_s, _Deref_inout_z_cap_c_(_Size) wchar_t, _Inout_z_cap_(_Count), wchar_t, _Dest, _In_z_ const wchar_t *, _Source, _In_ size_t, _Count)
    #pragma warning(pop)
    _Check_return_ _CRTIMP int __cdecl wcsncmp(_In_z_ const wchar_t * _Str1, _In_z_ const wchar_t * _Str2, _In_ size_t _MaxCount);
    #if __STDC_WANT_SECURE_LIB__
    _Check_return_wat_ _CRTIMP_ALTERNATIVE errno_t __cdecl wcsncpy_s(_Out_z_cap_(_SizeInWords) wchar_t * _Dst, _In_ rsize_t _SizeInWords, _In_z_ const wchar_t * _Src, _In_ rsize_t _MaxCount);
    #endif
    __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2(errno_t, wcsncpy_s, wchar_t, _Dest, _In_z_ const wchar_t *, _Source, _In_ size_t, _Count)
    __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_EX(wchar_t *, __RETURN_POLICY_DST, _CRTIMP, wcsncpy, wcsncpy_s, _Pre_notnull_ _Post_maybez_ wchar_t, _Out_cap_(_Count) _Post_maybez_, wchar_t, _Dest, _In_z_ const wchar_t *, _Source, _In_ size_t, _Count)
    _Check_return_ _CRTIMP _CONST_RETURN wchar_t * __cdecl wcspbrk(_In_z_ const wchar_t * _Str, _In_z_ const wchar_t * _Control);
    _Check_return_ _CRTIMP _CONST_RETURN wchar_t * __cdecl wcsrchr(_In_z_ const wchar_t * _Str, _In_ wchar_t _Ch);
    _Check_return_ _CRTIMP size_t __cdecl wcsspn(_In_z_ const wchar_t * _Str, _In_z_ const wchar_t * _Control);
    _Check_return_ _CRTIMP _CONST_RETURN wchar_t * __cdecl wcsstr(_In_z_ const wchar_t * _Str, _In_z_ const wchar_t * _SubStr);
    _Check_return_ _CRT_INSECURE_DEPRECATE(wcstok_s) _CRTIMP wchar_t * __cdecl wcstok(_Inout_opt_z_ wchar_t * _Str, _In_z_ const wchar_t * _Delim);
    #if __STDC_WANT_SECURE_LIB__
    _Check_return_ _CRTIMP_ALTERNATIVE wchar_t * __cdecl wcstok_s(_Inout_opt_z_ wchar_t * _Str, _In_z_ const wchar_t * _Delim, _Inout_ _Deref_prepost_opt_z_ wchar_t ** _Context);
    #endif
    _Check_return_ _CRT_INSECURE_DEPRECATE(_wcserror_s) _CRTIMP wchar_t * __cdecl _wcserror(_In_ int _ErrNum);
    _Check_return_wat_ _CRTIMP errno_t __cdecl _wcserror_s(_Out_opt_z_cap_(_SizeInWords) wchar_t * _Buf, _In_ size_t _SizeInWords, _In_ int _ErrNum);
    __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1(errno_t, _wcserror_s, wchar_t, _Buffer, _In_ int, _Error)
    _Check_return_ _CRT_INSECURE_DEPRECATE(__wcserror_s) _CRTIMP wchar_t * __cdecl __wcserror(_In_opt_z_ const wchar_t * _Str);
    _Check_return_wat_ _CRTIMP errno_t __cdecl __wcserror_s(_Out_opt_z_cap_(_SizeInWords) wchar_t * _Buffer, _In_ size_t _SizeInWords, _In_z_ const wchar_t * _ErrMsg);
    __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1(errno_t, __wcserror_s, wchar_t, _Buffer, _In_z_ const wchar_t *, _ErrorMessage)
    
    _Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t * _Str1, _In_z_ const wchar_t * _Str2);
    _Check_return_ _CRTIMP int __cdecl _wcsicmp_l(_In_z_ const wchar_t * _Str1, _In_z_ const wchar_t * _Str2, _In_opt_ _locale_t _Locale);
    _Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_z_ const wchar_t * _Str1, _In_z_ const wchar_t * _Str2, _In_ size_t _MaxCount);
    _Check_return_ _CRTIMP int __cdecl _wcsnicmp_l(_In_z_ const wchar_t * _Str1, _In_z_ const wchar_t * _Str2, _In_ size_t _MaxCount, _In_opt_ _locale_t _Locale);
    _Check_return_wat_ _CRTIMP_ALTERNATIVE errno_t __cdecl _wcsnset_s(_Inout_z_cap_(_SizeInWords) wchar_t * _Dst, _In_ size_t _SizeInWords, _In_ wchar_t _Val, _In_ size_t _MaxCount);
    __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2(errno_t, _wcsnset_s, _Deref_prepost_z_ wchar_t, _Dst, wchar_t, _Val, _In_ size_t, _MaxCount)
    __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_EX(wchar_t *, __RETURN_POLICY_DST, _CRTIMP, _wcsnset, _wcsnset_s, _Deref_inout_z_cap_c_(_Size) wchar_t, _Inout_z_cap_(_MaxCount), wchar_t, _Str, wchar_t, _Val, _In_ size_t, _MaxCount)
    _CRTIMP wchar_t * __cdecl _wcsrev(_Inout_z_ wchar_t * _Str);
    _Check_return_wat_ _CRTIMP_ALTERNATIVE errno_t __cdecl _wcsset_s(_Inout_z_cap_(_SizeInWords) wchar_t * _Dst, _In_ size_t _SizeInWords, _In_ wchar_t _Value);
    __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1(errno_t, _wcsset_s, _Deref_prepost_z_ wchar_t, _Str, wchar_t, _Val)
    __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1_EX(wchar_t *, __RETURN_POLICY_DST, _CRTIMP, _wcsset, _wcsset_s, _Deref_inout_z_cap_c_(_Size) wchar_t, _Inout_z_, wchar_t, _Str, wchar_t, _Val)
    
    _Check_return_wat_ _CRTIMP errno_t __cdecl _wcslwr_s(_Inout_z_cap_(_SizeInWords) wchar_t * _Str, _In_ size_t _SizeInWords);
    __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_0(errno_t, _wcslwr_s, _Deref_prepost_z_ wchar_t, _String)
    __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_0(wchar_t *, __RETURN_POLICY_DST, _CRTIMP, _wcslwr, _Inout_z_, wchar_t, _String)
    _Check_return_wat_ _CRTIMP errno_t __cdecl _wcslwr_s_l(_Inout_z_cap_(_SizeInWords) wchar_t * _Str, _In_ size_t _SizeInWords, _In_opt_ _locale_t _Locale);
    __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1(errno_t, _wcslwr_s_l, _Deref_prepost_z_ wchar_t, _String, _In_opt_ _locale_t, _Locale)
    __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1_EX(wchar_t *, __RETURN_POLICY_DST, _CRTIMP, _wcslwr_l, _wcslwr_s_l, _Deref_inout_z_cap_c_(_Size) wchar_t, _Inout_z_, wchar_t, _String, _In_opt_ _locale_t, _Locale)
    _Check_return_wat_ _CRTIMP errno_t __cdecl _wcsupr_s(_Inout_z_cap_(_Size) wchar_t * _Str, _In_ size_t _Size);
    __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_0(errno_t, _wcsupr_s, _Deref_prepost_z_ wchar_t, _String)
    __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_0(wchar_t *, __RETURN_POLICY_DST, _CRTIMP, _wcsupr, _Inout_z_, wchar_t, _String)
    _Check_return_wat_ _CRTIMP errno_t __cdecl _wcsupr_s_l(_Inout_z_cap_(_Size) wchar_t * _Str, _In_ size_t _Size, _In_opt_ _locale_t _Locale);
    __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1(errno_t, _wcsupr_s_l, _Deref_prepost_z_ wchar_t, _String, _In_opt_ _locale_t, _Locale)
    __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1_EX(wchar_t *, __RETURN_POLICY_DST, _CRTIMP, _wcsupr_l, _wcsupr_s_l, _Deref_inout_z_cap_c_(_Size) wchar_t, _Inout_z_, wchar_t, _String, _In_opt_ _locale_t, _Locale)
    _Check_return_opt_ _CRTIMP size_t __cdecl wcsxfrm(_Out_opt_cap_(_MaxCount) _Post_maybez_ wchar_t * _Dst, _In_z_ const wchar_t * _Src, _In_ size_t _MaxCount);
    _Check_return_opt_ _CRTIMP size_t __cdecl _wcsxfrm_l(_Out_opt_cap_(_MaxCount) _Post_maybez_ wchar_t * _Dst, _In_z_ const wchar_t *_Src, _In_ size_t _MaxCount, _In_opt_ _locale_t _Locale);
    _Check_return_ _CRTIMP int __cdecl wcscoll(_In_z_ const wchar_t * _Str1, _In_z_ const wchar_t * _Str2);
    _Check_return_ _CRTIMP int __cdecl _wcscoll_l(_In_z_ const wchar_t * _Str1, _In_z_ const wchar_t * _Str2, _In_opt_ _locale_t _Locale);
    _Check_return_ _CRTIMP int __cdecl _wcsicoll(_In_z_ const wchar_t * _Str1, _In_z_ const wchar_t * _Str2);
    _Check_return_ _CRTIMP int __cdecl _wcsicoll_l(_In_z_ const wchar_t * _Str1, _In_z_ const wchar_t *_Str2, _In_opt_ _locale_t _Locale);
    _Check_return_ _CRTIMP int __cdecl _wcsncoll(_In_z_ const wchar_t * _Str1, _In_z_ const wchar_t * _Str2, _In_ size_t _MaxCount);
    _Check_return_ _CRTIMP int __cdecl _wcsncoll_l(_In_z_ const wchar_t * _Str1, _In_z_ const wchar_t * _Str2, _In_ size_t _MaxCount, _In_opt_ _locale_t _Locale);
    _Check_return_ _CRTIMP int __cdecl _wcsnicoll(_In_z_ const wchar_t * _Str1, _In_z_ const wchar_t * _Str2, _In_ size_t _MaxCount);
    _Check_return_ _CRTIMP int __cdecl _wcsnicoll_l(_In_z_ const wchar_t * _Str1, _In_z_ const wchar_t * _Str2, _In_ size_t _MaxCount, _In_opt_ _locale_t _Locale);
    
    #ifdef  __cplusplus
    #ifndef _CPP_WIDE_INLINES_DEFINED
    #define _CPP_WIDE_INLINES_DEFINED
    extern "C++" {
    _Check_return_ inline wchar_t * __CRTDECL wcschr(_In_z_ wchar_t *_Str, wchar_t _Ch)
            {return ((wchar_t *)wcschr((const wchar_t *)_Str, _Ch)); }
    _Check_return_ inline wchar_t * __CRTDECL wcspbrk(_In_z_ wchar_t *_Str, _In_z_ const wchar_t *_Control)
            {return ((wchar_t *)wcspbrk((const wchar_t *)_Str, _Control)); }
    _Check_return_ inline wchar_t * __CRTDECL wcsrchr(_In_z_ wchar_t *_Str, _In_ wchar_t _Ch)
            {return ((wchar_t *)wcsrchr((const wchar_t *)_Str, _Ch)); }
    _Check_return_ inline wchar_t * __CRTDECL wcsstr(_In_z_ wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
            {return ((wchar_t *)wcsstr((const wchar_t *)_Str, _SubStr)); }
    }
    #endif
    #endif
    
    #if     !__STDC__
    
    #if defined(_DEBUG) && defined(_CRTDBG_MAP_ALLOC)
    #pragma push_macro("wcsdup")
    #undef wcsdup
    #endif
    
    _Check_return_ _CRT_NONSTDC_DEPRECATE(_wcsdup) _CRTIMP wchar_t * __cdecl wcsdup(_In_z_ const wchar_t * _Str);
    
    #if defined(_DEBUG) && defined(_CRTDBG_MAP_ALLOC)
    #pragma pop_macro("wcsdup")
    #endif
    
    /* old names */
    #define wcswcs wcsstr
    
    /* prototypes for oldnames.lib functions */
    _Check_return_ _CRT_NONSTDC_DEPRECATE(_wcsicmp) _CRTIMP int __cdecl wcsicmp(_In_z_ const wchar_t * _Str1, _In_z_ const wchar_t * _Str2);
    _Check_return_ _CRT_NONSTDC_DEPRECATE(_wcsnicmp) _CRTIMP int __cdecl wcsnicmp(_In_z_ const wchar_t * _Str1, _In_z_ const wchar_t * _Str2, _In_ size_t _MaxCount);
    _CRT_NONSTDC_DEPRECATE(_wcsnset) _CRTIMP wchar_t * __cdecl wcsnset(_Inout_z_cap_(_MaxCount) wchar_t * _Str, _In_ wchar_t _Val, _In_ size_t _MaxCount);
    _CRT_NONSTDC_DEPRECATE(_wcsrev) _CRTIMP wchar_t * __cdecl wcsrev(_Inout_z_ wchar_t * _Str);
    _CRT_NONSTDC_DEPRECATE(_wcsset) _CRTIMP wchar_t * __cdecl wcsset(_Inout_z_ wchar_t * _Str, wchar_t _Val);
    _CRT_NONSTDC_DEPRECATE(_wcslwr) _CRTIMP wchar_t * __cdecl wcslwr(_Inout_z_ wchar_t * _Str);
    _CRT_NONSTDC_DEPRECATE(_wcsupr) _CRTIMP wchar_t * __cdecl wcsupr(_Inout_z_ wchar_t * _Str);
    _Check_return_ _CRT_NONSTDC_DEPRECATE(_wcsicoll) _CRTIMP int __cdecl wcsicoll(_In_z_ const wchar_t * _Str1, _In_z_ const wchar_t * _Str2);
    
    #endif  /* !__STDC__ */
    
    #define _WSTRING_DEFINED
    #endif
    
    
    #ifdef  __cplusplus
    }
    #endif
    
    #endif  /* _INC_STRING */
    View Code

    在Vcinclude下面倒是有一个string的cpp文件,但是没有string操作函数的代码,那么strcpy,strcat源码到底在哪里?

    D:Program Filesvisual studioVCcrtsrc 目录下面

    这个目录下面包含所有C语言函数的源代码

    大多数函数的名字都是以名字命名的.c文件里,但是strcpy并没有strcpy.c文件,它的源码在strcat.c里面:

    strcat.c内容如下:

    /***
    *strcat.c - contains strcat() and strcpy()
     
    *
    *Purpose:
    *       Strcpy() copies one string onto another.
    *
    *       Strcat() concatenates (appends) a copy of the source string to the
    *       end of the destination string, returning the destination string.
    *
    *******************************************************************************/
    
    #include <cruntime.h>
    #include <string.h>
    
    #ifndef _MBSCAT
    #pragma function(strcat,strcpy)
    #endif  /* _MBSCAT */
    
    /***
    *char *strcat(dst, src) - concatenate (append) one string to another
    *
    *Purpose:
    *       Concatenates src onto the end of dest.  Assumes enough
    *       space in dest.
    *
    *Entry:
    *       char *dst - string to which "src" is to be appended
    *       const char *src - string to be appended to the end of "dst"
    *
    *Exit:
    *       The address of "dst"
    *
    *Exceptions:
    *
    *******************************************************************************/
    
    char * __cdecl strcat (
            char * dst,
            const char * src
            )
    {
            char * cp = dst;
    
            while( *cp )
                    cp++;                   /* find end of dst */
    /*不能写成while(*cp++)/ 因为这样的话为*cp为0时还会+1,导致cp执向了的后一个。
    while( *cp++ = *src++ ) ; /* Copy src to end of dst */ return( dst ); /* return dst */ } /*** *char *strcpy(dst, src) - copy one string over another * *Purpose: * Copies the string src into the spot specified by * dest; assumes enough room. * *Entry: * char * dst - string over which "src" is to be copied * const char * src - string to be copied over "dst" * *Exit: * The address of "dst" * *Exceptions: *******************************************************************************/ char * __cdecl strcpy(char * dst, const char * src) { char * cp = dst; while( *cp++ = *src++ ) ; /* Copy src over dst */ return( dst ); }

    strcpy另一种实现策略:

    林锐《高质量C++/C编程指南》

    #include <assert.h>
    char *strcpy(char *strDest, const char *strSrc)
    { 
    
        assert((strDest!=NULL) && (strSrc !=NULL)); // 2分 
    
        char *address = strDest;                   // 2分 
    
        while( (*strDest++ = * strSrc++) != ‘/0’ )   // 2分 
    
           ; 
    
        return address ;                          // 2分 
    
    }

    附:

    strcpy能把strSrc的内容复制到strDest,为什么还要char * 类型的返回值?

    答:为了实现链式表达式。 // 2分
    例如 int length = strlen( strcpy( strDest, “hello world”) );

    个人觉得 

     (*strDest++ = * strSrc++) != ‘/0’ 不能没有必要判断是否=0,因为但char内容为字符串结束符时ascii为0,dst=src; dst=0;
    while 判断dst是否等于0,等于0就退出了

    strcmp怎么写,最开始我这么写的:
    int strcmp(char *src,char *dst)
    {
        char *p=src,*q=dst;
        while( (*p!='') && (*q!=''))
        {
            if(*p==*q)
            {
                p++;
                q++;
            }
            else if(*p<*q)
            {
                return -1;
            }
            else
            {
                return 1;
            }
        }
        return 0;
    }

    表面上看没有问题,但是有很大的问题,但2个长度不等时,退出循环还是输出了0,。如de和def比较还是0.

    可以把return改下,判断*P和*q是否后面还有。显然太麻烦了。

    函数源码:

    /***
    *strcmp - compare two strings, returning less than, equal to, or greater than
    *
    *Purpose:
    *       STRCMP compares two strings and returns an integer
    *       to indicate whether the first is less than the second, the two are
    *       equal, or whether the first is greater than the second.
    *
    *       Comparison is done byte by byte on an UNSIGNED basis, which is to
    *       say that Null (0) is less than any other character (1-255).
    *
    *Entry:
    *       const char * src - string for left-hand side of comparison
    *       const char * dst - string for right-hand side of comparison
    *
    *Exit:
    *       returns -1 if src <  dst
    *       returns  0 if src == dst
    *       returns +1 if src >  dst
    *
    *Exceptions:
    *
    *******************************************************************************/
    
    int __cdecl strcmp (
            const char * src,
            const char * dst
            )
    {
            int ret = 0 ;
    
            while( ! (ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)
                    ++src, ++dst;
    
            if ( ret < 0 )
                    ret = -1 ;
            else if ( ret > 0 )
                    ret = 1 ;
    
            return( ret );
    }

    刚开始对

    while( ! (ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)
                    ++src, ++dst;
    不是很理解。
    如果是de和def比较,*src没有为0,还是在继续比较吗?
    刚开始我们认为是在继续比较,其实没有比较了。因为。
    ! ret
    ret=0才继续比较。
    ret=0-'f'=负数。
    !负数 为假。 0为假,非0为真。
    !0为真
    这里取非很巧妙。没有 用
    ! (ret = *(unsigned char *)src - *(unsigned char *)dst) && *src && *dst)这种。
    strcmp算法的可以有多种,不过我觉的可以把这么多算法分为两种:一种是利用减法运算判断结果,另一种是利用比较运算==得出结果。上面的就是用减法。判断。
    为什么要把src转成:
    unsigned char *

    这个函数要注意的几点:

    (1)使用*(unsigned char *)str1而不是用*str1。这是因为传入的参数为有符号数,

    有符号字符值的范围是-128-127,无符号字符值的范围是0-255,而字符串的ASCII没有负值,若不转化为无符号数,在减法实现时出现错误。

    例如:str的值为1,str2的值为255。

    作为无符号数计算时ret=-254,结果为负值,正确。

    作为有符号数计算时ret=-2,结果为正值,错误。

    ascii char范围为0-127,为什么上面说的255.怎么才能打印255的字符。

    在cmd下,按alt+255 回车,就可以打印ÿ。这个不是ascii字符。

    我们把这个字符粘贴到vs2010文件中,会提示当前编码文件为ascii格式,不能存储当前的字符,是否转换为unicode,转换为unicode就可以存储这个字符了。


    char *c="dÿ";
    printf("%s ",c);

    运行控制台会输出:

    d?

    ?说明第二个字符不可打印。

    (2)while循环中(ret=*(unsigned char *)str1 - *(unsigned char *)str2)&& *str1,最后的str1也可以换成str2,因为前面已经做了相减,无论哪个先为''都会退出

    (3)这个函数没有判断参数为NULL时的情况,所以当传入NULL时程序会崩溃。

    可以看到我们传递的参数有const,这会为面试加分。

    用比较实现

    int strcmp(const char *str1,const char * str2)
    
    {
    
      while((*str1)&&(*str1 == *str2))
    
      {
        str1++;
        str2++;
      }
    
      if(*(unsiged char *)str1 > *(unsiged char *)str2)
    
      {
        return 1;
    
      }
    
      else if(*(unsiged char *)str1 < *(unsiged char *)str2)
    
      {
    
        return -1;
    
      }
    
      else
    
      {
        return 0;
      }
    
    }

    注意:把while循环简写成while((*str1)&&(*str1++ == *str2++)) 

    当str1为abcd, str2为abfd时,由于判断到第三个字符时while推出,而str指针又加了1,str都指向第四个字符输出结果为0,显然 这是错误的。

    参考了:http://www.cnblogs.com/kaifublog/archive/2012/09/23/2699017.html

    strlen:
    int strlen(const char *str)
    {
        int len = 0;
           assert(str != NULL);
           while(*str++)
           {
                  len++;
           }
           return len;
    }

    我刚开始写的是:

    int strlen2(const char *src)
    {
        const char *p=src;
        int i=0;
        while(*p++)
            i++;
        return i;
    }

    用了一个临时的p来存储src,有没有必要,是没有必要的,调用时,形参只是copy一份实参的值,所以,src只是copy了一份

    原理src的值

    源码:

    size_t __cdecl strlen ( const char * str)
    {
            const char *eos = str;
    
            while( *eos++ ) ;
    
            return( eos - str - 1 );
    }

     用递归求:

    int strlen4(const char *str)
    {
        if(*str=='')
            return 0;
        else
            return strlen4(++str)+1;
    }

    有点非常值得注意,最开始我写的是strlen4(str++),程序崩溃了,为什么?

    每次函数内部调用时,str都指向h,strlen4(str)执行,str根本没动,导致了无穷递归,实在是一个很大的错误

    strncpy:

    原型:char * strncpy(char *dest, char *src,size_tnum);
    功能:(c/c++)复制src中的内容(字符,数字、汉字....)到dest,复制多少由num的值决定,返回指向dest的指针。如果遇到null字符(''),且还没有到num个字符时,就用(num - n)(n是遇到null字符前已经有的非null字符个数)个null字符附加到destination。注意:并不是添加到destination的最后,而是紧跟着由source中复制而来的字符后面。下面举例说明[1]
    char des[] = "Hello,i am!";
    char source[] = "abcdef";
    strncpy(des,source,5);
    此时,des区域是这样的:a,b,c,,,逗号,i,空格,a,m,!
    在测试时不要用prinf("%s"),因为遇到就结束了, 
    for(int i=0;i<sizeof(d)/sizeof(d[0]);i++)
            printf("%c",d[i]);
    注意:,并不是添加在!的后面。
    头文件:#include "string.h"
    说明:
    如果n > dest串长度,dest栈空间溢出产生崩溃异常。
    否则:
    1)src串长度<=dest串长度,(这里的串长度包含串尾NULL字符)
    如果n<src串长度,src的前n个字符复制到dest中。但是由于没有NULL字符,所以直接访问dest串会发生栈溢出的异常情况。
    如果n = src串长度,与strcpy一致。
    如果n >src串长度,src串存放于desk字串的[0,src串长度],dest串的(src串长度, dest串长度]处存放NULL。
    2)src串长度>dest串长度
    如果n =dest串长度,则dest串没有NULL字符,会导致输出会有乱码。如果不考虑src串复制完整性,可以将dest最后一字符置为NULL。
    综上,一般情况下,使用strncpy时,建议将n置为dest串长度(除非你将多个src串都复制到dest数组,并且从dest尾部反向操作),复制完毕后,为保险起见,将dest串最后一字符置NULL,避免发生在第2)种情况下的输出乱码问题。当然喽,无论是strcpy还是strncpy,保证src串长度<dest串长度才是最重要的。
    我的实现:
    char *strncpy2(char *dest,char *src,int num)
    {
        char *p=dest;
        int i=0;
        while( *src && (*p++=*src++) && (i<num))
            i++;
        if(i<num)
        {
            for(int j=1;j<=num-i;j++)
            {
                *p++='';
            }
        }
        return dest;
    }

    写这几行代码时经常发生各种各样的错误,如在for(j=1;j<num-i;j++)内,j写成了i,导致与前面的i重复。

    *p++=''写成*p='';导致最后一个num字符没有赋0.

    源码:

    /***
    *strncpy.c - copy at most n characters of string
    *
    *       Copyright (c) Microsoft Corporation. All rights reserved.
    *
    *Purpose:
    *       defines strncpy() - copy at most n characters of string
    *
    *******************************************************************************/
    
    #include <cruntime.h>
    #include <string.h>
    
    /***
    *char *strncpy(dest, source, count) - copy at most n characters
    *
    *Purpose:
    *       Copies count characters from the source string to the
    *       destination.  If count is less than the length of source,
    *       NO NULL CHARACTER is put onto the end of the copied string.
    *       If count is greater than the length of sources, dest is padded
    *       with null characters to length count.
    *
    *
    *Entry:
    *       char *dest - pointer to destination
    *       char *source - source string for copy
    *       unsigned count - max number of characters to copy
    *
    *Exit:
    *       returns dest
    *
    *Exceptions:
    *
    *******************************************************************************/
    
    char * __cdecl strncpy (
            char * dest,
            const char * source,
            size_t count
            )
    {
            char *start = dest;
    
            while (count && (*dest++ = *source++))    /* copy string */
                    count--;
    
            if (count)                              /* pad out with zeroes */
                    while (--count)
                            *dest++ = '';
    
            return(start);
    }

    为什么我写的代码比官方写的代码要长,因为我用了一个变量i 来计算,看有没有达到num,官方则自己用num--来判断。在while

    循环里用count来代替i<num.这样不加少了一个变量i,而且很紧凑。在后面的填充null时,也没用用j来技术,还是count字减。

    官方的源码写的漂亮

    strrev:

    自己写的:

    char * strrev2(char *src)
    {
        char *p,*q;
        p=src;
        q=src+strlen(src)-1;
        while(p<q)
        {
            char tmp=*p;*p=*q;*q=tmp; //注意是char tmp,我已经习惯写成int tmp
            p++;
            q--;
        }
        return src;
    }

    官方源码:

    char * __cdecl _strrev (
            char * string
            )
    {
            char *start = string;
            char *left = string;
            char ch;
    
            while (*string++)                 /* find end of string */
                    ;
            string -= 2;
    
            while (left < string)
            {
                    ch = *left;
                    *left++ = *string;
                    *string-- = ch;
            }
    
            return(start);
    }

    更多参考:

    http://www.cnblogs.com/JCSU/articles/1305401.html

    http://www.cnblogs.com/winnxm/archive/2011/05/17/2049266.html

    http://www.cppblog.com/dawnbreak/archive/2009/08/24/94262.html

     
  • 相关阅读:
    取得窗口大小和窗口位置兼容所有浏览器的js代码
    一个简单易用的导出Excel类
    如何快速启动chrome插件
    网页表单设计案例
    Ubuntu下的打包解包
    The source file is different from when the module was built. Would you like the debugger to use it anyway?
    FFisher分布
    kalman filter
    Group delay Matlab simulate
    24位位图格式解析
  • 原文地址:https://www.cnblogs.com/youxin/p/3270974.html
Copyright © 2011-2022 走看看