📄 wcstol.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
#include <corecrt.h>
/* flag values */
#define FL_UNSIGNED 1 /* wcstoul called */
#define FL_NEG 2 /* negative sign found */
#define FL_OVERFLOW 4 /* overflow occured */
#define FL_READDIGIT 8 /* we've read at least one correct digit */
static unsigned long __cdecl xstrtoxl(const char *nptr, const char **endptr, int ibase, int flags, BOOL bUnicode) {
const unsigned char *p;
wchar_t c;
unsigned long number;
unsigned digval;
unsigned long maxval;
if (ibase < 0 || ibase == 1 || ibase > 36) {
if (endptr)
*endptr = nptr;
return 0;
}
p = nptr; /* p is our scanning pointer */
number = 0; /* start with zero */
if (!bUnicode)
c = (WCHAR) (BYTE) *p++;
else
c = *((LPWSTR)p)++; /* read char */
while (iswspace(c)) {
if (!bUnicode)
c = (WCHAR)(BYTE)*p++;
else
c = *((LPWSTR)p)++; /* skip whitespace */
}
if ((c == L'-') || (c == L'+')) {
if (c == L'-')
flags |= FL_NEG; /* remember minus sign */
if (!bUnicode)
c = (WCHAR)(BYTE)*p++;
else
c = *((LPWSTR)p)++; /* read char */
}
if (!ibase)
ibase = (c != L'0') ? 10 : ((*p == 'x' || *p == 'X') && (!bUnicode || !p[1])) ? 16 : 8;
if ((ibase == 16) && (c == L'0') && (*p == 'x' || *p == 'X') && (!bUnicode || !p[1])) {
if (!bUnicode) {
++p;
c = *p++; /* advance past prefix */
} else {
++p;
++p;
c = *((LPWSTR)p)++; /* advance past prefix */
}
}
/* if our number exceeds this, we will overflow on multiply */
maxval = ULONG_MAX / ibase;
for (;;) { /* exit in middle of loop */
/* convert c to value */
if (isdigit(c))
digval = c - '0';
else if ((c>='A') && (c<='Z'))
digval = c - 'A' + 10;
else if ((c>='a') && (c<='z'))
digval = c - 'a' + 10;
else
break;
if (digval >= (unsigned)ibase)
break; /* exit loop if bad digit found */
/* record the fact we have read one digit */
flags |= FL_READDIGIT;
/* we now need to compute number = number * base + digval, but we
need to know if overflow occured. This requires a tricky pre-check. */
if (number < maxval || (number == maxval && (unsigned long)digval <= ULONG_MAX % ibase))
number = number * ibase + digval;
else
flags |= FL_OVERFLOW;
if (!bUnicode)
c = (WCHAR)(BYTE)*p++;
else
c = *((LPWSTR)p)++; /* read char */
}
--p; /* point to place that stopped scan */
if (bUnicode)
--p;
if (!(flags & FL_READDIGIT)) {
p = nptr;
number = 0;
} else if ((flags & FL_OVERFLOW) ||
(!(flags & FL_UNSIGNED) && (((flags & FL_NEG) && (number > -LONG_MIN)) ||
(!(flags & FL_NEG) && (number > LONG_MAX))))) {
number = (flags & FL_UNSIGNED) ? ULONG_MAX : (flags & FL_NEG) ? (unsigned long)(-LONG_MIN) : LONG_MAX;
}
if (endptr)
*endptr = p;
if (flags & FL_NEG)
number = (unsigned long)(-(long)number);
return number;
}
long __cdecl wcstol(const wchar_t *nptr, wchar_t **endptr, int ibase) {
return (long) xstrtoxl((const char *)nptr, (const char **)endptr, ibase, 0,1);
}
unsigned long __cdecl wcstoul(const wchar_t *nptr, wchar_t **endptr, int ibase) {
return xstrtoxl((const char *)nptr, (const char **)endptr, ibase, FL_UNSIGNED,1);
}
long __cdecl strtol(const char *nptr, char **endptr, int ibase) {
return (long) xstrtoxl(nptr, endptr, ibase, 0,0);
}
unsigned long __cdecl strtoul(const char *nptr, char **endptr, int ibase) {
return xstrtoxl(nptr, endptr, ibase, FL_UNSIGNED,0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -