| |

VerySource

 Forgot password?
 Register
Search
View: 14|Reply: 14

Is this interview question difficult? C expert please come in!

[Copy link]

1

Threads

1

Posts

2

Credits

Newbie

Rank: 1

Credits
2

 China

Post time: 2020-3-6 17:30:01
| Show all posts |Read mode
Ask the master:
Reimplement the sprintf (char * str, ...) library function in C!
Reply

Use magic Report

0

Threads

14

Posts

13

Credits

Newbie

Rank: 1

Credits
13

 United States

Post time: 2020-5-24 01:30:01
| Show all posts
It ’s not difficult, probably
#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;
}
Reply

Use magic Report

0

Threads

23

Posts

17

Credits

Newbie

Rank: 1

Credits
17

 China

Post time: 2020-5-28 09:45:01
| Show all posts
Possible topic requirements are
You cannot use these functions such as vsprintf, vsnprintf of the system.
Reply

Use magic Report

0

Threads

68

Posts

25

Credits

Newbie

Rank: 1

Credits
25

 China

Post time: 2020-6-5 07:45:02
| Show all posts
Format control,
Uncertain parameters,
There is nothing more ~~

Look at the implementation of printf/sprintf,
Reply

Use magic Report

0

Threads

28

Posts

16

Credits

Newbie

Rank: 1

Credits
16

 China

Post time: 2020-6-5 16:45:02
| Show all posts
It's really difficult if you write it yourself.
Reply

Use magic Report

0

Threads

3

Posts

3

Credits

Newbie

Rank: 1

Credits
3

 China

Post time: 2020-6-5 20:15:02
| Show all posts
What is the difference between printf/sprintf...
Reply

Use magic Report

0

Threads

5

Posts

5

Credits

Newbie

Rank: 1

Credits
5

 China

Post time: 2020-6-11 20:30:01
| Show all posts
This is nothing more than indefinite parameters,
Reply

Use magic Report

0

Threads

6

Posts

6

Credits

Newbie

Rank: 1

Credits
6

 China

Post time: 2020-6-15 14:30:01
| Show all posts
The implementation of CString::Format in WTL, you can refer to the following
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;
}
Reply

Use magic Report

0

Threads

6

Posts

6

Credits

Newbie

Rank: 1

Credits
6

 China

Post time: 2020-7-6 16:45:01
| Show all posts
It's not difficult, just formatting strings is a bit annoying~~
Reply

Use magic Report

0

Threads

5

Posts

5

Credits

Newbie

Rank: 1

Credits
5

 China

Post time: 7 day(s) ago
| Show all posts
/***
*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_ */
Reply

Use magic Report

You have to log in before you can reply Login | Register

Points Rules

Contact us|Archive|Mobile|CopyRight © 2008-2020|verysource.com ( 京ICP备17048824号-1 )

Quick Reply To Top Return to the list