How to detect when I am passing a std::string
, instead of a c_str()
to my variadic function?
My initial problem is that when I do pass a std::string
, instead of a c_str()
i.e., std::string s.c_str()
, to my variadic function, my program is going if I run if from shell script
on my Sublime Text build. This is what is happening, if I pass a std::string
and try to run if from Sublime Text:
rm -f main.exe
g++ --std=c++11 main.cpp -I . -o main
Starting the main program...
[Finished in 3.4s]
But if I run from a shell with ./main
, everything is OK, except the string print:
Starting the main program...
argumentsCount: 3
argumentsStringList[0]: ./main
argumentsStringList[1]: 1
argumentsStringList[2]: 2
SourceCode::SourceCode(1) text_code: ▒
Exiting main(2)
This is my function which do the parsing:
/**
* Missing string printf. This is safe and convenient but not exactly efficient.
*
* @param fmt a char array
* @param ... a variable length number of formating characters.
*
* @see http://stackoverflow.com/a/10150393/4934640
* @see http://stackoverflow.com/questions/2342162/stdstring-formatting-like-sprintf/10150393#10150393
*/
inline std::string format(const char* fmt, ...)
{
int size = 512;
char* buffer = new char[size];
va_list var_args;
va_start(var_args, fmt);
int nsize = vsnprintf(buffer, size, fmt, var_args);
//fail delete buffer and try again
if(size<=nsize)
{
delete[] buffer;
buffer = 0;
buffer = new char[nsize+1]; //+1 for /0
nsize = vsnprintf(buffer, size, fmt, var_args);
}
std::string ret(buffer);
va_end(var_args);
delete[] buffer;
return ret;
}
This is my tentative. It is a minimal practical example, you can run it on your own computer compiling with g++ --std=c++11 main.cpp -o main
:
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <cstdlib>
#include <cstdarg>
#include <typeinfo>
inline std::string format(const char* fmt, ...)
{
int size = 512;
char* buffer = new char[size];
std::string* temp;
va_list var_args_copy;
printf( "%s\n", fmt );
va_start(var_args_copy, fmt);
do
{
temp = va_arg( var_args_copy, std::string* );
if( typeid( temp ) == typeid( std::string* ) )
{
std::string message( "ERROR!!!!!!!!!!!!!! Bad formatted string!\n" );
return message;
}
} while( temp != NULL );
va_list var_args;
va_start(var_args, fmt);
int nsize = vsnprintf(buffer, size, fmt, var_args);
//fail delete buffer and try again
if(size<=nsize)
{
delete[] buffer;
buffer = 0;
buffer = new char[nsize+1]; //+1 for /0
nsize = vsnprintf(buffer, size, fmt, var_args);
}
std::string ret(buffer);
va_end(var_args);
delete[] buffer;
return ret;
}
int main( int argumentsCount, char* argumentsStringList[] )
{
printf( "" );
std::string strin( "String" );
std::cout << format( "1. The string is %s", strin ) << std::endl;
std::cout << format( "2. The string is %s", strin.c_str() ) << std::endl;
printf( "Exiting main(2)" );
return EXIT_SUCCESS;
}
Running my tentative, it outputs me this:
g++ -std=c++11 main2.cpp -I . -o main
1. The string is %s
ERROR!!!!!!!!!!!!!! Bad formatted string!
2. The string is %s
ERROR!!!!!!!!!!!!!! Bad formatted string!
Exiting main(2)[Finished in 3.7s]
Here the on the 2. The string is %s
, the ERROR!!!!!!!!!!!!!! Bad formatted string!
must not to be printed because it is not a std::string
. What is wrong about the typeid( temp ) == typeid( std::string* )
letting it pass by?
Anyways, another possible solution could be just accept std::string
instead of a c_str()
i.e., std::string s.c_str()
.