VerySource

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 2103|回复: 16

这道面试题是不是很难?C高手请进!

[复制链接]

1

主题

1

帖子

2.00

积分

新手上路

Rank: 1

积分
2.00
发表于 2020-3-6 17:30:01 | 显示全部楼层 |阅读模式
请教高手:
用C重新实现sprintf(char * str,...)库函数!
回复

使用道具 举报

0

主题

14

帖子

13.00

积分

新手上路

Rank: 1

积分
13.00
发表于 2020-5-24 01:30:01 | 显示全部楼层
不难的,大概就是这样
#include<stdarg.h>
int sprintf(char* str,char* szFormat, ...)
{
     int temp;
     va_list pArgList ;
     va_start (pArgList, szFormat) ;
     temp=_vsntprintf (str, MAXCOUNT, szFormat, pArgList) ;
     va_end (pArgList) ;
     return temp ;
}
回复

使用道具 举报

0

主题

25

帖子

19.00

积分

新手上路

Rank: 1

积分
19.00
发表于 2020-5-28 09:45:01 | 显示全部楼层
可能題目要求是
不能使用系統的這些vsprintf,vsnprintf之類函數實現.
回复

使用道具 举报

0

主题

78

帖子

29.00

积分

新手上路

Rank: 1

积分
29.00
发表于 2020-6-5 07:45:02 | 显示全部楼层
格式控制,
不定参数,
没有什么更多的内容了 ~~

看看 printf/sprintf 的实现,
回复

使用道具 举报

0

主题

41

帖子

28.00

积分

新手上路

Rank: 1

积分
28.00
发表于 2020-6-5 16:45:02 | 显示全部楼层
如果完全自己写的话确实很难。
回复

使用道具 举报

0

主题

3

帖子

3.00

积分

新手上路

Rank: 1

积分
3.00
发表于 2020-6-5 20:15:02 | 显示全部楼层
printf/sprintf有什么区别..........
回复

使用道具 举报

0

主题

8

帖子

6.00

积分

新手上路

Rank: 1

积分
6.00
发表于 2020-6-11 20:30:01 | 显示全部楼层
这个无非就是不定参数,
回复

使用道具 举报

0

主题

7

帖子

7.00

积分

新手上路

Rank: 1

积分
7.00
发表于 2020-6-15 14:30:01 | 显示全部楼层
WTL里CString::Format的实现,可以参考下
inline BOOL CString::FormatV(LPCTSTR lpszFormat, va_list argList)
{
        ATLASSERT(_IsValidString(lpszFormat));

        enum _FormatModifiers
        {
                FORCE_ANSI =        0x10000,
                FORCE_UNICODE =        0x20000,
                FORCE_INT64 =        0x40000
        };

        va_list argListSave = argList;

        // make a guess at the maximum length of the resulting string
        int nMaxLen = 0;
        for (LPCTSTR lpsz = lpszFormat; *lpsz != '\0'; lpsz = ::CharNext(lpsz))
        {
                // handle '%' character, but watch out for '%%'
                if (*lpsz != '%' || *(lpsz = ::CharNext(lpsz)) == '%')
                {
                        // this is instead of _tclen()
#if !defined(_UNICODE) && defined(_MBCS)
                        nMaxLen += (int)(::CharNext(lpsz) - lpsz);
#else
                        nMaxLen++;
#endif
                        continue;
                }

                int nItemLen = 0;

                // handle '%' character with format
                int nWidth = 0;
                for (; *lpsz != '\0'; lpsz = ::CharNext(lpsz))
                {
                        // check for valid flags
                        if (*lpsz == '#')
                                nMaxLen += 2;   // for '0x'
                        else if (*lpsz == '*')
                                nWidth = va_arg(argList, int);
                        else if (*lpsz == '-' || *lpsz == '+' || *lpsz == '0' || *lpsz == ' ')
                                ;
                        else // hit non-flag character
                                break;
                }
                // get width and skip it
                if (nWidth == 0)
                {
                        // width indicated by
                        nWidth = _cstrtoi(lpsz);
                        for (; *lpsz != '\0' && _cstrisdigit(*lpsz); lpsz = ::CharNext(lpsz))
                                ;
                }
                ATLASSERT(nWidth >= 0);

                int nPrecision = 0;
                if (*lpsz == '.')
                {
                        // skip past '.' separator (width.precision)
                        lpsz = ::CharNext(lpsz);

                        // get precision and skip it
                        if (*lpsz == '*')
                        {
                                nPrecision = va_arg(argList, int);
                                lpsz = ::CharNext(lpsz);
                        }
                        else
                        {
                                nPrecision = _cstrtoi(lpsz);
                                for (; *lpsz != '\0' && _cstrisdigit(*lpsz); lpsz = ::CharNext(lpsz))
                                        ;
                        }
                        ATLASSERT(nPrecision >= 0);
                }

                // should be on type modifier or specifier
                int nModifier = 0;
                if(lpsz[0] == _T('I') && lpsz[1] == _T('6') && lpsz[2] == _T('4'))
                {
                        lpsz += 3;
                        nModifier = FORCE_INT64;
                }
                else
                {
                        switch (*lpsz)
                        {
                        // modifiers that affect size
                        case 'h':
                                nModifier = FORCE_ANSI;
                                lpsz = ::CharNext(lpsz);
                                break;
                        case 'l':
                                nModifier = FORCE_UNICODE;
                                lpsz = ::CharNext(lpsz);
                                break;

                        // modifiers that do not affect size
                        case 'F':
                        case 'N':
                        case 'L':
                                lpsz = ::CharNext(lpsz);
                                break;
                        }
                }

                // now should be on specifier
                switch (*lpsz | nModifier)
                {
                // single characters
                case 'c':
                case 'C':
                        nItemLen = 2;
                        va_arg(argList, TCHAR);
                        break;
                case 'c' | FORCE_ANSI:
                case 'C' | FORCE_ANSI:
                        nItemLen = 2;
                        va_arg(argList, char);
                        break;
                case 'c' | FORCE_UNICODE:
                case 'C' | FORCE_UNICODE:
                        nItemLen = 2;
                        va_arg(argList, WCHAR);
                        break;

                // strings
                case 's':
                {
                        LPCTSTR pstrNextArg = va_arg(argList, LPCTSTR);
                        if (pstrNextArg == NULL)
                        {
                                nItemLen = 6;  // "(null)"
                        }
                        else
                        {
                                nItemLen = lstrlen(pstrNextArg);
                                nItemLen = max(1, nItemLen);
                        }
                        break;
                }

                case 'S':
                {
#ifndef _UNICODE
                        LPWSTR pstrNextArg = va_arg(argList, LPWSTR);
                        if (pstrNextArg == NULL)
                        {
                                nItemLen = 6;  // "(null)"
                        }
                        else
                        {
                                nItemLen = (int)wcslen(pstrNextArg);
                                nItemLen = max(1, nItemLen);
                        }
#else //_UNICODE
                        LPCSTR pstrNextArg = va_arg(argList, LPCSTR);
                        if (pstrNextArg == NULL)
                        {
                                nItemLen = 6; // "(null)"
                        }
                        else
                        {
                                nItemLen = lstrlenA(pstrNextArg);
                                nItemLen = max(1, nItemLen);
                        }
#endif //_UNICODE
                        break;
                }

                case 's' | FORCE_ANSI:
                case 'S' | FORCE_ANSI:
                {
                        LPCSTR pstrNextArg = va_arg(argList, LPCSTR);
                        if (pstrNextArg == NULL)
                        {
                                nItemLen = 6; // "(null)"
                        }
                        else
                        {
                                nItemLen = lstrlenA(pstrNextArg);
                                nItemLen = max(1, nItemLen);
                        }
                        break;
                }

                case 's' | FORCE_UNICODE:
                case 'S' | FORCE_UNICODE:
                {
                        LPWSTR pstrNextArg = va_arg(argList, LPWSTR);
                        if (pstrNextArg == NULL)
                        {
                                nItemLen = 6; // "(null)"
                        }
                        else
                        {
                                nItemLen = (int)wcslen(pstrNextArg);
                                nItemLen = max(1, nItemLen);
                        }
                        break;
                }
                }

                // adjust nItemLen for strings
                if (nItemLen != 0)
                {
                        nItemLen = max(nItemLen, nWidth);
                        if (nPrecision != 0)
                                nItemLen = min(nItemLen, nPrecision);
                }
                else
                {
                        switch (*lpsz)
                        {
                        // integers
                        case 'd':
                        case 'i':
                        case 'u':
                        case 'x':
                        case 'X':
                        case 'o':
                                if (nModifier & FORCE_INT64)
                                        va_arg(argList, __int64);
                                else
                                        va_arg(argList, int);
                                nItemLen = 32;
                                nItemLen = max(nItemLen, nWidth + nPrecision);
                                break;

#ifndef _ATL_USE_CSTRING_FLOAT
                        case 'e':
                        case 'E':
                        case 'f':
                        case 'g':
                        case 'G':
                                ATLASSERT(!"Floating point (%%e, %%E, %%f, %%g, and %%G) is not supported by the WTL::CString class.");
#ifndef _DEBUG
                                ::OutputDebugString(_T("Floating point (%%e, %%f, %%g, and %%G) is not supported by the WTL::CString class."));
#ifndef _WIN32_WCE
                                ::DebugBreak();
#else // CE specific
                                DebugBreak();
#endif //_WIN32_WCE
#endif //!_DEBUG
                                break;
#else //_ATL_USE_CSTRING_FLOAT
                        case 'e':
                        case 'E':
                        case 'g':
                        case 'G':
                                va_arg(argList, double);
                                nItemLen = 128;
                                nItemLen = max(nItemLen, nWidth + nPrecision);
                                break;
                        case 'f':
                                {
                                        double f;
                                        LPTSTR pszTemp;

                                        // 312 == strlen("-1+(309 zeroes).")
                                        // 309 zeroes == max precision of a double
                                        // 6 == adjustment in case precision is not specified,
                                        //   which means that the precision defaults to 6
                                        pszTemp = (LPTSTR)_alloca(max(nWidth, 312 + nPrecision + 6));

                                        f = va_arg(argList, double);
                                        _stprintf(pszTemp, _T( "%*.*f" ), nWidth, nPrecision + 6, f);
                                        nItemLen = _tcslen(pszTemp);
                                }
                                break;
#endif //_ATL_USE_CSTRING_FLOAT

                        case 'p':
                                va_arg(argList, void*);
                                nItemLen = 32;
                                nItemLen = max(nItemLen, nWidth + nPrecision);
                                break;

                        // no output
                        case 'n':
                                va_arg(argList, int*);
                                break;

                        default:
                                ATLASSERT(FALSE);  // unknown formatting option
                        }
                }

                // adjust nMaxLen for output nItemLen
                nMaxLen += nItemLen;
        }

        if(GetBuffer(nMaxLen) == NULL)
                return FALSE;
#ifndef _ATL_USE_CSTRING_FLOAT
        int nRet = wvsprintf(m_pchData, lpszFormat, argListSave);
#else //_ATL_USE_CSTRING_FLOAT
        int nRet = _vstprintf(m_pchData, lpszFormat, argListSave);
#endif //_ATL_USE_CSTRING_FLOAT
        nRet;   // ref
        ATLASSERT(nRet <= GetAllocLength());
        ReleaseBuffer();

        va_end(argListSave);
        return TRUE;
}

// formatting (using wsprintf style formatting)
inline BOOL __cdecl CString::Format(LPCTSTR lpszFormat, ...)
{
        ATLASSERT(_IsValidString(lpszFormat));

        va_list argList;
        va_start(argList, lpszFormat);
        BOOL bRet = FormatV(lpszFormat, argList);
        va_end(argList);
        return bRet;
}
回复

使用道具 举报

0

主题

10

帖子

7.00

积分

新手上路

Rank: 1

积分
7.00
发表于 2020-7-6 16:45:01 | 显示全部楼层
不难,就是格式化字符串有点烦~~
回复

使用道具 举报

0

主题

9

帖子

8.00

积分

新手上路

Rank: 1

积分
8.00
发表于 2020-7-8 21:30:01 | 显示全部楼层
/***
*sprintf.c - print formatted to string
*
*       Copyright (c) Microsoft Corporation. All rights reserved.
*
*Purpose:
*       defines sprintf() and _snprintf() - print formatted data to string
*
*******************************************************************************/

#include <cruntime.h>
#include <stdio.h>
#include <dbgint.h>
#include <stdarg.h>
#include <internal.h>
#include <limits.h>
#include <mtdll.h>
#include <stddef.h>

#define MAXSTR INT_MAX


/***
*ifndef _COUNT_
*int sprintf(string, format, ...) - print formatted data to string
*else
*int _snprintf(string, cnt, format, ...) - print formatted data to string
*endif
*
*Purpose:
*       Prints formatted data to the using the format string to
*       format data and getting as many arguments as called for
*       Sets up a FILE so file i/o operations can be used, make
*       string look like a huge buffer to it, but _flsbuf will
*       refuse to flush it if it fills up.  Appends '\0' to make
*       it a true string. _output does the real work here
*
*       Allocate the 'fake' _iob[] entry statically instead of on
*       the stack so that other routines can assume that _iob[]
*       entries are in are in DGROUP and, thus, are near.
*
*ifdef _COUNT_
*       The _snprintf() flavor takes a count argument that is
*       the max number of bytes that should be written to the
*       user's buffer.
*endif
*
*       Multi-thread: (1) Since there is no stream, this routine must
*       never try to get the stream lock (i.e., there is no stream
*       lock either). (2) Also, since there is only one statically
*       allocated 'fake' iob, we must lock/unlock to prevent collisions.
*
*Entry:
*       char *string - pointer to place to put output
*ifdef _COUNT_
*       size_t count - max number of bytes to put in buffer
*endif
*       char *format - format string to control data format/number
*       of arguments followed by list of arguments, number and type
*       controlled by format string
*
*Exit:
*       returns number of characters printed
*
*Exceptions:
*
*******************************************************************************/

#ifndef _COUNT_

int __cdecl sprintf (
        char *string,
        const char *format,
        ...
        )
#else  /* _COUNT_ */

#ifndef _SWPRINTFS_ERROR_RETURN_FIX

int __cdecl _snprintf (
        char *string,
        size_t count,
        const char *format,
        ...
        )
#else  /* _SWPRINTFS_ERROR_RETURN_FIX */

int __cdecl _snprintf_c (
        char *string,
        size_t count,
        const char *format,
        ...
        )

#endif  /* _SWPRINTFS_ERROR_RETURN_FIX */

#endif  /* _COUNT_ */

{
        FILE str;
        REG1 FILE *outfile = &str;
        va_list arglist;
        REG2 int retval;

        _VALIDATE_RETURN( (format != NULL), EINVAL, -1);

#ifdef _COUNT_
        _VALIDATE_RETURN( (count == 0) || (string != NULL), EINVAL, -1 );
#else  /* _COUNT_ */
        _VALIDATE_RETURN( (string != NULL), EINVAL, -1 );
#endif  /* _COUNT_ */
        va_start(arglist, format);

#ifndef _COUNT_
        outfile->_cnt = MAXSTR;
#else  /* _COUNT_ */
        if(count>INT_MAX)
        {
            /* old-style functions allow any large value to mean unbounded */
            outfile->_cnt = INT_MAX;
        }
        else
        {
            outfile->_cnt = (int)(count);
        }
#endif  /* _COUNT_ */
        outfile->_flag = _IOWRT|_IOSTRG;
        outfile->_ptr = outfile->_base = string;

        retval = _output_l(outfile,format,NULL,arglist);

        if (string == NULL)
            return(retval);

#ifndef _SWPRINTFS_ERROR_RETURN_FIX
        _putc_nolock('\0',outfile); /* no-lock version */

        return(retval);
#else  /* _SWPRINTFS_ERROR_RETURN_FIX */
        if((retval >= 0) && (_putc_nolock('\0',outfile) != EOF))
            return(retval);

        string[0] = 0;
        return -1;
#endif  /* _SWPRINTFS_ERROR_RETURN_FIX */
}

#ifndef _COUNT_

int __cdecl _sprintf_l (
        char *string,
        const char *format,
        _locale_t plocinfo,
        ...
        )
{
    va_list arglist;
    va_start(arglist, plocinfo);

#pragma warning(push)
#pragma warning(disable:4996) // Disable deprecation warning since calling function is also deprecated
    return _vsprintf_l(string, format, plocinfo, arglist);
#pragma warning(pop)
}

#else  /* _COUNT_ */
#ifndef _SWPRINTFS_ERROR_RETURN_FIX

int __cdecl _snprintf_l (
        char *string,
        size_t count,
        const char *format,
        _locale_t plocinfo,
        ...
        )
{
    va_list arglist;
    va_start(arglist, plocinfo);

#pragma warning(push)
#pragma warning(disable:4996) // Disable deprecation warning since calling function is also deprecated
    return _vsnprintf_l(string, count, format, plocinfo, arglist);
#pragma warning(pop)
}
#else  /* _SWPRINTFS_ERROR_RETURN_FIX */

int __cdecl _snprintf_c_l (
        char *string,
        size_t count,
        const char *format,
        _locale_t plocinfo,
        ...
        )
{
    va_list arglist;
    va_start(arglist, plocinfo);

    return _vsnprintf_c_l(string, count, format, plocinfo, arglist);

}

#endif  /* _SWPRINTFS_ERROR_RETURN_FIX */
#endif  /* _COUNT_ */
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|CopyRight © 2008-2023|verysource.com ( 京ICP备17048824号-1 )

快速回复 返回顶部 返回列表