⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 strftime.c

📁 C语言库函数的原型,有用的拿去
💻 C
📖 第 1 页 / 共 3 页
字号:


/***
*_store_num() - Convert a number to ascii and copy it
*
*Purpose:
*       Convert the supplied number to decimal and store
*       in the output buffer.  Update both the count and
*       buffer pointers.
*
*       *** For internal use with strftime() only ***
*
*Entry:
*       int num                 = pointer to integer value
*       int digits              = # of ascii digits to put into string
*       char **out              = address of pointer to output string
*       size_t *count           = address of char count (space in output area)
*       unsigned no_lead_zeros  = flag indicating that padding by leading
*                                 zeros is not necessary
*
*Exit:
*       none
*Exceptions:
*
*******************************************************************************/

static void __cdecl _store_num (
        int num,
        int digits,
        char **out,
        size_t *count,
        unsigned no_lead_zeros
        )
{
        int temp = 0;

        if (no_lead_zeros) {
            _store_number (num, out, count);
            return;
        }

        if ((size_t)digits < *count)  {
            for (digits--; (digits+1); digits--) {
                (*out)[digits] = (char)('0' + num % 10);
                num /= 10;
                temp++;
            }
            *out += temp;
            *count -= temp;
        }
        else
            *count = 0;
}

/***
*_store_number() - Convert positive integer to string
*
*Purpose:
*       Convert positive integer to a string and store it in the output
*       buffer with no null terminator.  Update both the count and
*       buffer pointers.
*
*       Differs from _store_num in that the precision is not specified,
*       and no leading zeros are added.
*
*       *** For internal use with strftime() only ***
*
*       Created from xtoi.c
*
*Entry:
*       int num = pointer to integer value
*       char **out = address of pointer to output string
*       size_t *count = address of char count (space in output area)
*
*Exit:
*       none
*
*Exceptions:
*       The buffer is filled until it is out of space.  There is no
*       way to tell beforehand (as in _store_num) if the buffer will
*       run out of space.
*
*******************************************************************************/

static void __cdecl _store_number (
        int num,
        char **out,
        size_t *count
        )
{
        char *p;                /* pointer to traverse string */
        char *firstdig;         /* pointer to first digit */
        char temp;              /* temp char */

        p = *out;

        /* put the digits in the buffer in reverse order */
        if (*count > 1)
        {
            do {
                *p++ = (char) (num % 10 + '0');
                (*count)--;
            } while ((num/=10) > 0 && *count > 1);
        }

        firstdig = *out;                /* firstdig points to first digit */
        *out = p;                       /* return pointer to next space */
        p--;                            /* p points to last digit */

        /* reverse the buffer */
        do {
            temp = *p;
            *p-- = *firstdig;
            *firstdig++ = temp;     /* swap *p and *firstdig */
        } while (firstdig < p);         /* repeat until halfway */
}


/***
*_store_winword() - Store date/time in WinWord format
*
*Purpose:
*       Format the date/time in the supplied WinWord format
*       and store it in the supplied buffer.
*
*       *** For internal use with strftime() only ***
*
*       For simple localized Gregorian calendars (calendar type 1), the WinWord
*       format is converted token by token to strftime conversion specifiers.
*       _expandtime is then called to do the work.  The WinWord format is
*       expected to be a character string (not wide-chars).
*
*       For other calendar types, the Win32 APIs GetDateFormat/GetTimeFormat
*       are instead used to do all formatting, so that this routine doesn't
*       have to know about era/period strings, year offsets, etc.
*
*
*Entry:
*       int field_code = code for ww_* field with format
*       const struct tm *tmptr = pointer to time/date structure
*       char **out = address of pointer to output string
*       size_t *count = address of char count (space in output area)
*       struct __lc_time_data *lc_time = pointer to locale-specific info
*
*Exit:
*       BOOL true for success, false for failure
*
*Exceptions:
*
*******************************************************************************/

static BOOL __cdecl _store_winword (
        _locale_t plocinfo,
        int field_code,
        const struct tm *tmptr,
        char **out,
        size_t *count,
        struct __lc_time_data *lc_time
        )
{
        const char *format;
        char specifier;
        const char *p;
        int repeat;
        char *ampmstr;
        unsigned no_lead_zeros;

        switch (field_code)
        {
        case WW_SDATEFMT:
            format = lc_time->ww_sdatefmt;
            break;
        case WW_LDATEFMT:
            format = lc_time->ww_ldatefmt;
            break;
        case WW_TIMEFMT:
        default:
            format = lc_time->ww_timefmt;
            break;
        }

        if (lc_time->ww_caltype != 1)
        {
            /* We have something other than the basic Gregorian calendar */

            SYSTEMTIME SystemTime;
            int cch;
            int (WINAPI * FormatFunc)(LCID, DWORD, const SYSTEMTIME *,
                                      LPCSTR, LPSTR, int);

            if (field_code != WW_TIMEFMT)
                FormatFunc = GetDateFormat;
            else
                FormatFunc = GetTimeFormat;

            /* We leave the verification of SystemTime up to GetDateFormat or GetTimeFormat;
               if one of those function returns 0 to indicate error, we will fall through and
               call _expandtime() again.
             */
            SystemTime.wYear   = (WORD)(tmptr->tm_year + 1900);
            SystemTime.wMonth  = (WORD)(tmptr->tm_mon + 1);
            SystemTime.wDay    = (WORD)(tmptr->tm_mday);
            SystemTime.wHour   = (WORD)(tmptr->tm_hour);
            SystemTime.wMinute = (WORD)(tmptr->tm_min);
            SystemTime.wSecond = (WORD)(tmptr->tm_sec);
            SystemTime.wMilliseconds = 0;

            /* Find buffer size required */
            cch = FormatFunc(lc_time->ww_lcid, 0, &SystemTime,
                             format, NULL, 0);

            if (cch != 0)
            {
                char *buffer;

                /* Allocate buffer, first try stack, then heap */
                buffer = (char *)_malloca(cch);
                if (buffer != NULL)
                {
                    /* Do actual date/time formatting */
                    cch = FormatFunc(lc_time->ww_lcid, 0, &SystemTime,
                                     format, buffer, cch);

                    /* Copy to output buffer */
                    p = buffer;
                    while (--cch > 0 && *count > 0) {
                        *(*out)++ = *p++;
                        (*count)--;
                    }

                    _freea(buffer);
                    return TRUE;
                }
            }

            /* In case of error, just fall through to localized Gregorian */
        }

        while (*format && *count != 0)
        {
            specifier = 0;          /* indicate no match */
            no_lead_zeros = 0;      /* default is print leading zeros */

            /* count the number of repetitions of this character */
            for (repeat=0, p=format; *p++ == *format; repeat++);
            /* leave p pointing to the beginning of the next token */
            p--;

            /* switch on ascii format character and determine specifier */
            switch (*format)
            {
            case 'M':
                switch (repeat)
                {
                case 1: no_lead_zeros = 1;  /* fall thru */
                case 2: specifier = 'm'; break;
                case 3: specifier = 'b'; break;
                case 4: specifier = 'B'; break;
                } break;
            case 'd':
                switch (repeat)
                {
                case 1: no_lead_zeros = 1;  /* fall thru */
                case 2: specifier = 'd'; break;
                case 3: specifier = 'a'; break;
                case 4: specifier = 'A'; break;
                } break;
            case 'y':
                switch (repeat)
                {
                case 2: specifier = 'y'; break;
                case 4: specifier = 'Y'; break;
                } break;
            case 'h':
                switch (repeat)
                {
                case 1: no_lead_zeros = 1;  /* fall thru */
                case 2: specifier = 'I'; break;
                } break;
            case 'H':
                switch (repeat)
                {
                case 1: no_lead_zeros = 1;  /* fall thru */
                case 2: specifier = 'H'; break;
                } break;
            case 'm':
                switch (repeat)
                {
                case 1: no_lead_zeros = 1;  /* fall thru */
                case 2: specifier = 'M'; break;
                } break;
            case 's': /* for compatibility; not strictly WinWord */
                switch (repeat)
                {
                case 1: no_lead_zeros = 1;  /* fall thru */
                case 2: specifier = 'S'; break;
                } break;
            case 'A':
            case 'a':
                if (!__ascii_stricmp(format, "am/pm"))
                    p = format + 5;
                else if (!__ascii_stricmp(format, "a/p"))
                    p = format + 3;
                specifier = 'p';
                break;
            case 't': /* t or tt time marker suffix */
                if ( tmptr->tm_hour <= 11 )
                    ampmstr = lc_time->ampm[0];
                else
                    ampmstr = lc_time->ampm[1];

                if ( (repeat == 1) && (*count > 0) ) {
                    if ( _isleadbyte_l((int)*ampmstr, plocinfo) && (*count > 1) )
                    {
                        /* catch \0 directly following leadbyte - invalid MBCS sequence, and do not copy to output */
                        if(ampmstr[1]=='\0')
                        {
                            _ASSERTE(("Invalid MBCS character sequence found in locale AMPM string",0));
                            return FALSE;
                        }

                        *(*out)++ = *ampmstr++;
                        (*count)--;
                    }

                    *(*out)++ = *ampmstr++;
                    (*count)--;
                } else {
                    while (*ampmstr != 0 && *count > 0) {
                        if (_isleadbyte_l((int)*ampmstr, plocinfo) && *count > 1) {
                            /* handle dud string leadbyte, EOS */
                            if(ampmstr[1]=='\0')
                            {
                                _ASSERTE(("Invalid MBCS character sequence found in locale AMPM string",0));
                                return FALSE;
                            }
                            *(*out)++ = *ampmstr++;
                            (*count)--;
                        }
                        *(*out)++ = *ampmstr++;
                        (*count)--;
                    }
                }
                format = p;
                continue;

            case '\'': /* literal string */
                if (repeat & 1) /* odd number */
                {
                    format += repeat;
                    while (*format && *count != 0)
                    {
                        if (*format == '\'')
                        {
                            format++;
                            break;
                        }
                        if ( _isleadbyte_l((int)*format, plocinfo) && (*count > 1) )
                        {
                            /* catch \0 directly following leadbyte - invalid MBCS sequence, and do not copy to output */
                            if(format[1]=='\0')
                            {
                                _ASSERTE(("Invalid MBCS character sequence passed into strftime",0));
                                return FALSE;
                            }

                            *(*out)++ = *format++;
                            (*count)--;
                        }

                        *(*out)++ = *format++;
                        (*count)--;
                    }
                }
                else { /* even number */
                    format += repeat;
                }
                continue;

            default: /* non-control char, print it */
                break;
            } /* switch */

            /* expand specifier, or copy literal if specifier not found */
            if (specifier)
            {
                if (!_expandtime( plocinfo,
                             specifier,
                             tmptr,
                             out,
                             count,
                             lc_time,
                             no_lead_zeros))
                {
                    return FALSE;
                }
                format = p; /* bump format up to the next token */
            } else {
                if ( _isleadbyte_l((int)*format, plocinfo) && (*count > 1))
                {
                    /* catch \0 directly following leadbyte - invalid MBCS sequence, and do not copy to output */
                    if(format[1]=='\0')
                    {
                        _ASSERTE(("Invalid MBCS character sequence passed into strftime",0));
                        return FALSE;
                    }

                    *(*out)++ = *format++;
                    (*count)--;
                }
                *(*out)++ = *format++;
                (*count)--;
            }
        } /* while */

        return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -