📄 string.c
字号:
}
/*************************************************************************
* SHLWAPI_StrStrHelperA
*
* Internal implementation of StrStrA/StrStrIA
*/
static LPSTR SHLWAPI_StrStrHelperA(LPCSTR lpszStr, LPCSTR lpszSearch,
int (*pStrCmpFn)(LPCSTR,LPCSTR,size_t))
{
size_t iLen;
if (!lpszStr || !lpszSearch || !*lpszSearch)
return NULL;
iLen = strlen(lpszSearch);
while (*lpszStr)
{
if (!pStrCmpFn(lpszStr, lpszSearch, iLen))
return (LPSTR)lpszStr;
lpszStr = CharNextA(lpszStr);
}
return NULL;
}
/*************************************************************************
* StrStrA [SHLWAPI.@]
*
* Find a substring within a string.
*
* PARAMS
* lpszStr [I] String to search in
* lpszSearch [I] String to look for
*
* RETURNS
* The start of lpszSearch within lpszStr, or NULL if not found.
*/
LPSTR WINAPI StrStrA(LPCSTR lpszStr, LPCSTR lpszSearch)
{
TRACE("(%s,%s)\n", debugstr_a(lpszStr), debugstr_a(lpszSearch));
return SHLWAPI_StrStrHelperA(lpszStr, lpszSearch, strncmp);
}
/*************************************************************************
* StrStrW [SHLWAPI.@]
*
* See StrStrA.
*/
LPWSTR WINAPI StrStrW(LPCWSTR lpszStr, LPCWSTR lpszSearch)
{
if (!lpszStr || !lpszSearch) return NULL;
return strstrW( lpszStr, lpszSearch );
}
/*************************************************************************
* StrRStrIA [SHLWAPI.@]
*
* Find the last occurrence of a substring within a string.
*
* PARAMS
* lpszStr [I] String to search in
* lpszEnd [I] End of lpszStr
* lpszSearch [I] String to look for
*
* RETURNS
* The last occurrence lpszSearch within lpszStr, or NULL if not found.
*/
LPSTR WINAPI StrRStrIA(LPCSTR lpszStr, LPCSTR lpszEnd, LPCSTR lpszSearch)
{
WORD ch1, ch2;
INT iLen;
TRACE("(%s,%s)\n", debugstr_a(lpszStr), debugstr_a(lpszSearch));
if (!lpszStr || !lpszSearch || !*lpszSearch)
return NULL;
if (!lpszEnd)
lpszEnd = lpszStr + lstrlenA(lpszStr);
if (lpszEnd == lpszStr)
return NULL;
if (IsDBCSLeadByte(*lpszSearch))
ch1 = *lpszSearch << 8 | (UCHAR)lpszSearch[1];
else
ch1 = *lpszSearch;
iLen = lstrlenA(lpszSearch);
do
{
lpszEnd = CharPrevA(lpszStr, lpszEnd);
ch2 = IsDBCSLeadByte(*lpszEnd)? *lpszEnd << 8 | (UCHAR)lpszEnd[1] : *lpszEnd;
if (!ChrCmpIA(ch1, ch2))
{
if (!StrCmpNIA(lpszEnd, lpszSearch, iLen))
return (LPSTR)lpszEnd;
}
} while (lpszEnd > lpszStr);
return NULL;
}
/*************************************************************************
* StrRStrIW [SHLWAPI.@]
*
* See StrRStrIA.
*/
LPWSTR WINAPI StrRStrIW(LPCWSTR lpszStr, LPCWSTR lpszEnd, LPCWSTR lpszSearch)
{
INT iLen;
TRACE("(%s,%s)\n", debugstr_w(lpszStr), debugstr_w(lpszSearch));
if (!lpszStr || !lpszSearch || !*lpszSearch)
return NULL;
if (!lpszEnd)
lpszEnd = lpszStr + strlenW(lpszStr);
iLen = strlenW(lpszSearch);
while (lpszEnd > lpszStr)
{
lpszEnd--;
if (!StrCmpNIW(lpszEnd, lpszSearch, iLen))
return (LPWSTR)lpszEnd;
}
return NULL;
}
/*************************************************************************
* StrStrIA [SHLWAPI.@]
*
* Find a substring within a string, ignoring case.
*
* PARAMS
* lpszStr [I] String to search in
* lpszSearch [I] String to look for
*
* RETURNS
* The start of lpszSearch within lpszStr, or NULL if not found.
*/
LPSTR WINAPI StrStrIA(LPCSTR lpszStr, LPCSTR lpszSearch)
{
TRACE("(%s,%s)\n", debugstr_a(lpszStr), debugstr_a(lpszSearch));
return SHLWAPI_StrStrHelperA(lpszStr, lpszSearch, strncasecmp);
}
/*************************************************************************
* StrStrIW [SHLWAPI.@]
*
* See StrStrIA.
*/
LPWSTR WINAPI StrStrIW(LPCWSTR lpszStr, LPCWSTR lpszSearch)
{
int iLen;
TRACE("(%s,%s)\n", debugstr_w(lpszStr), debugstr_w(lpszSearch));
if (!lpszStr || !lpszSearch || !*lpszSearch)
return NULL;
iLen = strlenW(lpszSearch);
while (*lpszStr)
{
if (!StrCmpNIW(lpszStr, lpszSearch, iLen))
return (LPWSTR)lpszStr;
lpszStr++;
}
return NULL;
}
/*************************************************************************
* StrToIntA [SHLWAPI.@]
*
* Read a signed integer from a string.
*
* PARAMS
* lpszStr [I] String to read integer from
*
* RETURNS
* The signed integer value represented by the string, or 0 if no integer is
* present.
*
* NOTES
* No leading space is allowed before the number, although a leading '-' is.
*/
int WINAPI StrToIntA(LPCSTR lpszStr)
{
int iRet = 0;
TRACE("(%s)\n", debugstr_a(lpszStr));
if (!lpszStr)
{
WARN("Invalid lpszStr would crash under Win32!\n");
return 0;
}
if (*lpszStr == '-' || isdigit(*lpszStr))
StrToIntExA(lpszStr, 0, &iRet);
return iRet;
}
/*************************************************************************
* StrToIntW [SHLWAPI.@]
*
* See StrToIntA.
*/
int WINAPI StrToIntW(LPCWSTR lpszStr)
{
int iRet = 0;
TRACE("(%s)\n", debugstr_w(lpszStr));
if (!lpszStr)
{
WARN("Invalid lpszStr would crash under Win32!\n");
return 0;
}
if (*lpszStr == '-' || isdigitW(*lpszStr))
StrToIntExW(lpszStr, 0, &iRet);
return iRet;
}
/*************************************************************************
* StrToIntExA [SHLWAPI.@]
*
* Read an integer from a string.
*
* PARAMS
* lpszStr [I] String to read integer from
* dwFlags [I] Flags controlling the conversion
* lpiRet [O] Destination for read integer.
*
* RETURNS
* Success: TRUE. lpiRet contains the integer value represented by the string.
* Failure: FALSE, if the string is invalid, or no number is present.
*
* NOTES
* Leading whitespace, '-' and '+' are allowed before the number. If
* dwFlags includes STIF_SUPPORT_HEX, hexadecimal numbers are allowed, if
* preceded by '0x'. If this flag is not set, or there is no '0x' prefix,
* the string is treated as a decimal string. A leading '-' is ignored for
* hexadecimal numbers.
*/
BOOL WINAPI StrToIntExA(LPCSTR lpszStr, DWORD dwFlags, LPINT lpiRet)
{
BOOL bNegative = FALSE;
int iRet = 0;
TRACE("(%s,%08X,%p)\n", debugstr_a(lpszStr), dwFlags, lpiRet);
if (!lpszStr || !lpiRet)
{
WARN("Invalid parameter would crash under Win32!\n");
return FALSE;
}
if (dwFlags > STIF_SUPPORT_HEX)
{
WARN("Unknown flags (%08lX)!\n", dwFlags & ~STIF_SUPPORT_HEX);
}
/* Skip leading space, '+', '-' */
while (isspace(*lpszStr))
lpszStr = CharNextA(lpszStr);
if (*lpszStr == '-')
{
bNegative = TRUE;
lpszStr++;
}
else if (*lpszStr == '+')
lpszStr++;
if (dwFlags & STIF_SUPPORT_HEX &&
*lpszStr == '0' && tolower(lpszStr[1]) == 'x')
{
/* Read hex number */
lpszStr += 2;
if (!isxdigit(*lpszStr))
return FALSE;
while (isxdigit(*lpszStr))
{
iRet = iRet * 16;
if (isdigit(*lpszStr))
iRet += (*lpszStr - '0');
else
iRet += 10 + (tolower(*lpszStr) - 'a');
lpszStr++;
}
*lpiRet = iRet;
return TRUE;
}
/* Read decimal number */
if (!isdigit(*lpszStr))
return FALSE;
while (isdigit(*lpszStr))
{
iRet = iRet * 10;
iRet += (*lpszStr - '0');
lpszStr++;
}
*lpiRet = bNegative ? -iRet : iRet;
return TRUE;
}
/*************************************************************************
* StrToIntExW [SHLWAPI.@]
*
* See StrToIntExA.
*/
BOOL WINAPI StrToIntExW(LPCWSTR lpszStr, DWORD dwFlags, LPINT lpiRet)
{
BOOL bNegative = FALSE;
int iRet = 0;
TRACE("(%s,%08X,%p)\n", debugstr_w(lpszStr), dwFlags, lpiRet);
if (!lpszStr || !lpiRet)
{
WARN("Invalid parameter would crash under Win32!\n");
return FALSE;
}
if (dwFlags > STIF_SUPPORT_HEX)
{
WARN("Unknown flags (%08lX)!\n", dwFlags & ~STIF_SUPPORT_HEX);
}
/* Skip leading space, '+', '-' */
while (isspaceW(*lpszStr)) lpszStr++;
if (*lpszStr == '-')
{
bNegative = TRUE;
lpszStr++;
}
else if (*lpszStr == '+')
lpszStr++;
if (dwFlags & STIF_SUPPORT_HEX &&
*lpszStr == '0' && tolowerW(lpszStr[1]) == 'x')
{
/* Read hex number */
lpszStr += 2;
if (!isxdigitW(*lpszStr))
return FALSE;
while (isxdigitW(*lpszStr))
{
iRet = iRet * 16;
if (isdigitW(*lpszStr))
iRet += (*lpszStr - '0');
else
iRet += 10 + (tolowerW(*lpszStr) - 'a');
lpszStr++;
}
*lpiRet = iRet;
return TRUE;
}
/* Read decimal number */
if (!isdigitW(*lpszStr))
return FALSE;
while (isdigitW(*lpszStr))
{
iRet = iRet * 10;
iRet += (*lpszStr - '0');
lpszStr++;
}
*lpiRet = bNegative ? -iRet : iRet;
return TRUE;
}
/*************************************************************************
* StrDupA [SHLWAPI.@]
*
* Duplicate a string.
*
* PARAMS
* lpszStr [I] String to duplicate.
*
* RETURNS
* Success: A pointer to a new string containing the contents of lpszStr
* Failure: NULL, if memory cannot be allocated
*
* NOTES
* The string memory is allocated with LocalAlloc(), and so should be released
* by calling LocalFree().
*/
LPSTR WINAPI StrDupA(LPCSTR lpszStr)
{
int iLen;
LPSTR lpszRet;
TRACE("(%s)\n",debugstr_a(lpszStr));
iLen = lpszStr ? strlen(lpszStr) + 1 : 1;
lpszRet = (LPSTR)LocalAlloc(LMEM_FIXED, iLen);
if (lpszRet)
{
if (lpszStr)
memcpy(lpszRet, lpszStr, iLen);
else
*lpszRet = '\0';
}
return lpszRet;
}
/*************************************************************************
* StrDupW [SHLWAPI.@]
*
* See StrDupA.
*/
LPWSTR WINAPI StrDupW(LPCWSTR lpszStr)
{
int iLen;
LPWSTR lpszRet;
TRACE("(%s)\n",debugstr_w(lpszStr));
iLen = (lpszStr ? strlenW(lpszStr) + 1 : 1) * sizeof(WCHAR);
lpszRet = (LPWSTR)LocalAlloc(LMEM_FIXED, iLen);
if (lpszRet)
{
if (lpszStr)
memcpy(lpszRet, lpszStr, iLen);
else
*lpszRet = '\0';
}
return lpszRet;
}
/*************************************************************************
* SHLWAPI_StrSpnHelperA
*
* Internal implementation of StrSpnA/StrCSpnA/StrCSpnIA
*/
static int SHLWAPI_StrSpnHelperA(LPCSTR lpszStr, LPCSTR lpszMatch,
LPSTR (WINAPI *pStrChrFn)(LPCSTR,WORD),
BOOL bInvert)
{
LPCSTR lpszRead = lpszStr;
if (lpszStr && *lpszStr && lpszMatch)
{
while (*lpszRead)
{
LPCSTR lpszTest = pStrChrFn(lpszMatch, *lpszRead);
if (!bInvert && !lpszTest)
break;
if (bInvert && lpszTest)
break;
lpszRead = CharNextA(lpszRead);
};
}
return lpszRead - lpszStr;
}
/*************************************************************************
* StrSpnA [SHLWAPI.@]
*
* Find the length of the start of a string that contains only certain
* characters.
*
* PARAMS
* lpszStr [I] String to search
* lpszMatch [I] Characters that can be in the substring
*
* RETURNS
* The length of the part of lpszStr containing only chars from lpszMatch,
* or 0 if any parameter is invalid.
*/
int WINAPI StrSpnA(LPCSTR lpszStr, LPCSTR lpszMatch)
{
TRACE("(%s,%s)\n",debugstr_a(lpszStr), debugstr_a(lpszMatch));
return SHLWAPI_StrSpnHelperA(lpszStr, lpszMatch, StrChrA, FALSE);
}
/*************************************************************************
* StrSpnW [SHLWAPI.@]
*
* See StrSpnA.
*/
int WINAPI StrSpnW(LPCWSTR lpszStr, LPCWSTR lpszMatch)
{
if (!lpszStr || !lpszMatch) return 0;
return strspnW( lpszStr, lpszMatch );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -