Solved

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

Posted on 2001-07-25
7
348 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
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 30

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
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 30

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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
maze travler 6 47
how to import Image file in turbo c++ ? 6 48
Handling string inputs in C/Linux 23 168
Unable to start eclipse ? 17 86
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…
Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
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.

762 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

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now