is there a function like sprtinf but only returns len of string

is there a function like sprintf () but instead of copying to a buffer it just returns the len of the final string?

int i = 100, y;

y = somefunc ("%i", i);

now y equals 3 is there something like that?
LVL 1
Kitty__KongAsked:
Who is Participating?
 
nietodConnect With a Mentor Commented:
But if the goal is to learn how long the strign will be, so that you can supply a sufficiently long string to sprintf(), then this doesn't help.   If that is the case, you are stuck.   In general, there is no way to learn how long the string should be that you pass to sprintf().  This is one of MANY reasons why sprintf() is often unsafe to use.

Instead of using sprintf(), which has known flaws, why not switch to the C++ way of performign these operations, which were developed to correct the flaws?   You can use a C++ strignstream instead.  This allows you to format output just like sptrinf(), but the data is stored in a C++ string object.  Since strigns expand their storage requirements as needed, this allows the output string to be any length required.
0
 
makerpCommented:
i do not think so,

char buffer[10];
sprintf(buffer,"%i",i);
printf("the string is %d long\n",strlen(buffer));

i would just do that
0
 
ZoppoCommented:
I agree with makerp, only the code can be made a bit easier:
char buffer[10];
int len = sprintf(buffer,"%i",i);
printf("the string is %d long\n",len);

ZOPPO
0
Cloud Class® Course: Ruby Fundamentals

This course will introduce you to Ruby, as well as teach you about classes, methods, variables, data structures, loops, enumerable methods, and finishing touches.

 
ZoppoCommented:
Here's code which can be used to determine the expected length for a printf() as part
of CString-implementation of MFC:

void CString::FormatV(LPCTSTR lpszFormat, va_list argList)
{
      ASSERT(AfxIsValidString(lpszFormat));

      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 = _tcsinc(lpsz))
      {
            // handle '%' character, but watch out for '%%'
            if (*lpsz != '%' || *(lpsz = _tcsinc(lpsz)) == '%')
            {
                  nMaxLen += _tclen(lpsz);
                  continue;
            }

            int nItemLen = 0;

            // handle '%' character with format
            int nWidth = 0;
            for (; *lpsz != '\0'; lpsz = _tcsinc(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 = _ttoi(lpsz);
                  for (; *lpsz != '\0' && _istdigit(*lpsz); lpsz = _tcsinc(lpsz))
                        ;
            }
            ASSERT(nWidth >= 0);

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

                  // get precision and skip it
                  if (*lpsz == '*')
                  {
                        nPrecision = va_arg(argList, int);
                        lpsz = _tcsinc(lpsz);
                  }
                  else
                  {
                        nPrecision = _ttoi(lpsz);
                        for (; *lpsz != '\0' && _istdigit(*lpsz); lpsz = _tcsinc(lpsz))
                              ;
                  }
                  ASSERT(nPrecision >= 0);
            }

            // should be on type modifier or specifier
            int nModifier = 0;
            if (_tcsncmp(lpsz, _T("I64"), 3) == 0)
            {
                  lpsz += 3;
                  nModifier = FORCE_INT64;
#if !defined(_X86_) && !defined(_ALPHA_)
                  // __int64 is only available on X86 and ALPHA platforms
                  ASSERT(FALSE);
#endif
            }
            else
            {
                  switch (*lpsz)
                  {
                  // modifiers that affect size
                  case 'h':
                        nModifier = FORCE_ANSI;
                        lpsz = _tcsinc(lpsz);
                        break;
                  case 'l':
                        nModifier = FORCE_UNICODE;
                        lpsz = _tcsinc(lpsz);
                        break;

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

            // now should be on specifier
            switch (*lpsz | nModifier)
            {
            // single characters
            case 'c':
            case 'C':
                  nItemLen = 2;
                  va_arg(argList, TCHAR_ARG);
                  break;
            case 'c'|FORCE_ANSI:
            case 'C'|FORCE_ANSI:
                  nItemLen = 2;
                  va_arg(argList, CHAR_ARG);
                  break;
            case 'c'|FORCE_UNICODE:
            case 'C'|FORCE_UNICODE:
                  nItemLen = 2;
                  va_arg(argList, WCHAR_ARG);
                  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 = wcslen(pstrNextArg);
                           nItemLen = max(1, nItemLen);
                        }
#else
                        LPCSTR pstrNextArg = va_arg(argList, LPCSTR);
                        if (pstrNextArg == NULL)
                           nItemLen = 6; // "(null)"
                        else
                        {
                           nItemLen = lstrlenA(pstrNextArg);
                           nItemLen = max(1, nItemLen);
                        }
#endif
                  }
                  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 = wcslen(pstrNextArg);
                           nItemLen = max(1, nItemLen);
                        }
                  }
                  break;
            }

            // adjust nItemLen for strings
            if (nItemLen != 0)
            {
                  if (nPrecision != 0)
                        nItemLen = min(nItemLen, nPrecision);
                  nItemLen = max(nItemLen, nWidth);
            }
            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;

                  case 'e':
                  case 'g':
                  case 'G':
                        va_arg(argList, DOUBLE_ARG);
                        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;

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

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

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

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

      GetBuffer(nMaxLen);
      VERIFY(_vstprintf(m_pchData, lpszFormat, argListSave) <= GetAllocLength());
      ReleaseBuffer();

      va_end(argListSave);
}

// formatting (using wsprintf style formatting)
void AFX_CDECL CString::Format(LPCTSTR lpszFormat, ...)
{
      ASSERT(AfxIsValidString(lpszFormat));

      va_list argList;
      va_start(argList, lpszFormat);
      FormatV(lpszFormat, argList);
      va_end(argList);
}

maybe it's a help,

ZOPPO
0
 
Black_EndCommented:
Why not use _snprintf
0
 
llewelmCommented:
I'm assuming the goal based on the flow of the comments above but...If the goal is ultimately to store the formatted string into a buffer why not simply use the CString::Format function to format the string and store it within a CString object as follows.

CString lcsData;
int liValue = 10;

lcsData.Format ("My value is %d", liValue);

If you really want the length at that point just do:

printf ("Length = %d\n", lcsData.GetLength());
0
 
nietodCommented:
>> Why not use _snprintf
That is not a standard function.  how do we know if Kittykong's compiler supports it?  And if todes, it it wise to use a non-portable function like that?

>> why not simply use the CString
Because CString is specific to MFC and there is no evidence that this pgrogram has anythign to do with MFC

however a string string object is portable.  it will owrk on all platforms and with all compilers.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.