Skip to main content
Rollback to Revision 2
Source Link
Jamal
  • 34.9k
  • 13
  • 133
  • 237

I know that stringstreams are the C++ recommended way to create formatted text. However, they can often become quite verbose, especially when compared to the succinct format strings of printf and family. However, the printf family can lead to its own issues, with buffer overflow issues, and so I would rather not use these functions directly

My goal was to make a function to behave similarly to snprintf, but return a std::string, avoiding any chance of buffer overflow. Knowing that there are many pitfalls to string manipulation in C++, have I exposed myself to any errors in using this function?

EDIT: At vnp's suggestion, using a char* as input to allow for additional type-checking, and having a workaround for alternative vsnprintf behavior.

#include <cstdio>
#include <cstdarg>
#include <string>

__attribute__((format (printf, 1, 2)))
std::string string_sprintf(const char*std::string& format, ...){
  static const int initial_buf_size = 100;
  va_list arglist;
  va_start(arglist, format);
  char buf[initial_buf_size];buf1[initial_buf_size];
  const int len = vsnprintf(bufbuf1,initial_buf_size,format, arglist);
  va_end(arglist);

  if(len+1<initial_buf_size){
    return buf;
  } else if(len==-1){
    //VS2013 returns -1 for too long strings
    long buf_size = initial_buf_size;
    while.c_str(len==-1){
      buf_size *= 10;
      char long_buf[buf_size];
      va_start(arglist,format);
      len = vsnprintf(long_buf,buf_size,format,arglist);
   + 1;
  va_end(arglist);
     
  if(len>0len<initial_buf_size){
        return long_buf;
      }
    }buf1;
  } else {
    char long_buf[len+1];buf2[len];
    va_start(arglist,format);
    vsnprintf(long_bufbuf2,len,format.c_str(),arglist);
    va_end(arglist);
    return buf;buf2;
  }
}

I know that stringstreams are the C++ recommended way to create formatted text. However, they can often become quite verbose, especially when compared to the succinct format strings of printf and family. However, the printf family can lead to its own issues, with buffer overflow issues, and so I would rather not use these functions directly

My goal was to make a function to behave similarly to snprintf, but return a std::string, avoiding any chance of buffer overflow. Knowing that there are many pitfalls to string manipulation in C++, have I exposed myself to any errors in using this function?

EDIT: At vnp's suggestion, using a char* as input to allow for additional type-checking, and having a workaround for alternative vsnprintf behavior.

#include <cstdio>
#include <cstdarg>
#include <string>

__attribute__((format (printf, 1, 2)))
std::string string_sprintf(const char* format, ...){
  static const int initial_buf_size = 100;
  va_list arglist;
  va_start(arglist, format);
  char buf[initial_buf_size];
  int len = vsnprintf(buf,initial_buf_size,format, arglist);
  va_end(arglist);

  if(len+1<initial_buf_size){
    return buf;
  } else if(len==-1){
    //VS2013 returns -1 for too long strings
    long buf_size = initial_buf_size;
    while(len==-1){
      buf_size *= 10;
      char long_buf[buf_size];
      va_start(arglist,format);
      len = vsnprintf(long_buf,buf_size,format,arglist);
      va_end(arglist);
      if(len>0){
        return long_buf;
      }
    }
  } else {
    char long_buf[len+1];
    va_start(arglist,format);
    vsnprintf(long_buf,len,format,arglist);
    va_end(arglist);
    return buf;
  }
}

I know that stringstreams are the C++ recommended way to create formatted text. However, they can often become quite verbose, especially when compared to the succinct format strings of printf and family. However, the printf family can lead to its own issues, with buffer overflow issues, and so I would rather not use these functions directly

My goal was to make a function to behave similarly to snprintf, but return a std::string, avoiding any chance of buffer overflow. Knowing that there are many pitfalls to string manipulation in C++, have I exposed myself to any errors in using this function?

#include <cstdio>
#include <cstdarg>
#include <string>

std::string string_sprintf(const std::string& format, ...){
  static const int initial_buf_size = 100;
  va_list arglist;
  va_start(arglist, format);
  char buf1[initial_buf_size];
  const int len = vsnprintf(buf1,initial_buf_size,format.c_str(), arglist) + 1;
  va_end(arglist);
 
  if(len<initial_buf_size){
    return buf1;
  } else {
    char buf2[len];
    va_start(arglist,format);
    vsnprintf(buf2,len,format.c_str(),arglist);
    va_end(arglist);
    return buf2;
  }
}
Work around VS2013 vsnprintf behavior, switch to const char* as input instead of std::string.
Source Link

I know that stringstreams are the C++ recommended way to create formatted text. However, they can often become quite verbose, especially when compared to the succinct format strings of printf and family. However, the printf family can lead to its own issues, with buffer overflow issues, and so I would rather not use these functions directly

My goal was to make a function to behave similarly to snprintf, but return a std::string, avoiding any chance of buffer overflow. Knowing that there are many pitfalls to string manipulation in C++, have I exposed myself to any errors in using this function?

EDIT: At vnp's suggestion, using a char* as input to allow for additional type-checking, and having a workaround for alternative vsnprintf behavior.

#include <cstdio>
#include <cstdarg>
#include <string>

__attribute__((format (printf, 1, 2)))
std::string string_sprintf(const std::string&char* format, ...){
  static const int initial_buf_size = 100;
  va_list arglist;
  va_start(arglist, format);
  char buf1[initial_buf_size];buf[initial_buf_size];
  const int len = vsnprintf(buf1buf,initial_buf_size,format.c_str, arglist);
  va_end(arglist),;

  if(len+1<initial_buf_size){
    return buf;
  } else if(len==-1){
    //VS2013 returns -1 for too long strings
    long buf_size = initial_buf_size;
    while(len==-1){
      buf_size *= 10;
      char long_buf[buf_size];
      va_start(arglist,format);
 + 1;    len = vsnprintf(long_buf,buf_size,format,arglist);
      va_end(arglist);
 
      if(len<initial_buf_sizelen>0){
        return buf1;long_buf;
      }
    }
  } else {
    char buf2[len];long_buf[len+1];
    va_start(arglist,format);
    vsnprintf(buf2long_buf,len,format.c_str(),arglist);
    va_end(arglist);
    return buf2;buf;
  }
}

I know that stringstreams are the C++ recommended way to create formatted text. However, they can often become quite verbose, especially when compared to the succinct format strings of printf and family. However, the printf family can lead to its own issues, with buffer overflow issues, and so I would rather not use these functions directly

My goal was to make a function to behave similarly to snprintf, but return a std::string, avoiding any chance of buffer overflow. Knowing that there are many pitfalls to string manipulation in C++, have I exposed myself to any errors in using this function?

#include <cstdio>
#include <cstdarg>
#include <string>

std::string string_sprintf(const std::string& format, ...){
  static const int initial_buf_size = 100;
  va_list arglist;
  va_start(arglist, format);
  char buf1[initial_buf_size];
  const int len = vsnprintf(buf1,initial_buf_size,format.c_str(), arglist) + 1;
  va_end(arglist);
 
  if(len<initial_buf_size){
    return buf1;
  } else {
    char buf2[len];
    va_start(arglist,format);
    vsnprintf(buf2,len,format.c_str(),arglist);
    va_end(arglist);
    return buf2;
  }
}

I know that stringstreams are the C++ recommended way to create formatted text. However, they can often become quite verbose, especially when compared to the succinct format strings of printf and family. However, the printf family can lead to its own issues, with buffer overflow issues, and so I would rather not use these functions directly

My goal was to make a function to behave similarly to snprintf, but return a std::string, avoiding any chance of buffer overflow. Knowing that there are many pitfalls to string manipulation in C++, have I exposed myself to any errors in using this function?

EDIT: At vnp's suggestion, using a char* as input to allow for additional type-checking, and having a workaround for alternative vsnprintf behavior.

#include <cstdio>
#include <cstdarg>
#include <string>

__attribute__((format (printf, 1, 2)))
std::string string_sprintf(const char* format, ...){
  static const int initial_buf_size = 100;
  va_list arglist;
  va_start(arglist, format);
  char buf[initial_buf_size];
  int len = vsnprintf(buf,initial_buf_size,format, arglist);
  va_end(arglist);

  if(len+1<initial_buf_size){
    return buf;
  } else if(len==-1){
    //VS2013 returns -1 for too long strings
    long buf_size = initial_buf_size;
    while(len==-1){
      buf_size *= 10;
      char long_buf[buf_size];
      va_start(arglist,format);
      len = vsnprintf(long_buf,buf_size,format,arglist);
      va_end(arglist);
      if(len>0){
        return long_buf;
      }
    }
  } else {
    char long_buf[len+1];
    va_start(arglist,format);
    vsnprintf(long_buf,len,format,arglist);
    va_end(arglist);
    return buf;
  }
}
deleted 28 characters in body; edited title
Source Link
Jamal
  • 34.9k
  • 13
  • 133
  • 237

c++, mimic Mimic sprintf with std::string output

I know that stringstreams are the C++ recommended way to create formatted text. However, they can often become quite verbose, especially when compared to the succinct format strings of printf and family. However, the printf family can lead to its own issues, with buffer overflow issues, and so I would rather not use these functions directly

My goal was to make a function to behave similarly to snprintf, but return a std::string, avoiding any chance of buffer overflow. Knowing that there are many pitfalls to string manipulation in C++, have I exposed myself to any errors in using this function?

<!-- language: c++ -->
#include <cstdio>
#include <cstdarg>
#include <string>

std::string string_sprintf(const std::string& format, ...){
  static const int initial_buf_size = 100;
  va_list arglist;
  va_start(arglist, format);
  char buf1[initial_buf_size];
  const int len = vsnprintf(buf1,initial_buf_size,format.c_str(), arglist) + 1;
  va_end(arglist);

  if(len<initial_buf_size){
    return buf1;
  } else {
    char buf2[len];
    va_start(arglist,format);
    vsnprintf(buf2,len,format.c_str(),arglist);
    va_end(arglist);
    return buf2;
  }
}

c++, mimic sprintf with std::string output

I know that stringstreams are the C++ recommended way to create formatted text. However, they can often become quite verbose, especially when compared to the succinct format strings of printf and family. However, the printf family can lead to its own issues, with buffer overflow issues, and so I would rather not use these functions directly

My goal was to make a function to behave similarly to snprintf, but return a std::string, avoiding any chance of buffer overflow. Knowing that there are many pitfalls to string manipulation in C++, have I exposed myself to any errors in using this function?

<!-- language: c++ -->
#include <cstdio>
#include <cstdarg>
#include <string>

std::string string_sprintf(const std::string& format, ...){
  static const int initial_buf_size = 100;
  va_list arglist;
  va_start(arglist, format);
  char buf1[initial_buf_size];
  const int len = vsnprintf(buf1,initial_buf_size,format.c_str(), arglist) + 1;
  va_end(arglist);

  if(len<initial_buf_size){
    return buf1;
  } else {
    char buf2[len];
    va_start(arglist,format);
    vsnprintf(buf2,len,format.c_str(),arglist);
    va_end(arglist);
    return buf2;
  }
}

Mimic sprintf with std::string output

I know that stringstreams are the C++ recommended way to create formatted text. However, they can often become quite verbose, especially when compared to the succinct format strings of printf and family. However, the printf family can lead to its own issues, with buffer overflow issues, and so I would rather not use these functions directly

My goal was to make a function to behave similarly to snprintf, but return a std::string, avoiding any chance of buffer overflow. Knowing that there are many pitfalls to string manipulation in C++, have I exposed myself to any errors in using this function?

#include <cstdio>
#include <cstdarg>
#include <string>

std::string string_sprintf(const std::string& format, ...){
  static const int initial_buf_size = 100;
  va_list arglist;
  va_start(arglist, format);
  char buf1[initial_buf_size];
  const int len = vsnprintf(buf1,initial_buf_size,format.c_str(), arglist) + 1;
  va_end(arglist);

  if(len<initial_buf_size){
    return buf1;
  } else {
    char buf2[len];
    va_start(arglist,format);
    vsnprintf(buf2,len,format.c_str(),arglist);
    va_end(arglist);
    return buf2;
  }
}
Source Link
Loading