Solved

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

Posted on 2001-07-25
7
387 Views
Last Modified: 2007-12-19
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?
0
Comment
Question by:Kitty__Kong
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
7 Comments
 
LVL 10

Expert Comment

by:makerp
ID: 6316687
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
 
LVL 31

Expert Comment

by:Zoppo
ID: 6316700
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
 
LVL 22

Accepted Solution

by:
nietod earned 40 total points
ID: 6316826
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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 31

Expert Comment

by:Zoppo
ID: 6317115
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
 
LVL 1

Expert Comment

by:Black_End
ID: 6318066
Why not use _snprintf
0
 
LVL 1

Expert Comment

by:llewelm
ID: 6318277
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
 
LVL 22

Expert Comment

by:nietod
ID: 6319112
>> 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

Featured Post

[Live Webinar] The Cloud Skills Gap

As Cloud technologies come of age, business leaders grapple with the impact it has on their team's skills and the gap associated with the use of a cloud platform.

Join experts from 451 Research and Concerto Cloud Services on July 27th where we will examine fact and fiction.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

623 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question