Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

String.Format alternative in C++ [duplicate]

I don't have much experience working with C++. Rather I have worked more in C# and so, I wanted to ask my question by relating to what I would have done in there. I have to generate a specific format of the string, which I have to pass to another function. In C#, I would have easily generated the string through the below simple code.

string a = "test"; string b = "text.txt"; string c = "text1.txt";  String.Format("{0} {1} > {2}", a, b, c); 

By generating such an above string, I should be able to pass this in system(). However, system only accepts char*

I am on Win32 C++ (not C++/CLI), and cannot use boost since it would include too much inclusion of all the files for a project which itself is very small. Something like sprintf() looks useful to me, but sprintf does not accept string as the a, b and c parameters. Any suggestions how I can generate these formatted strings to pass to system in my program?

like image 226
user1240679 Avatar asked May 02 '12 08:05

user1240679


People also ask

What is the format string for double?

Just use %. 2f as the format specifier. This will make the Java printf format a double to two decimal places.

Is Fstring faster than format?

As of Python 3.6, f-strings are a great new way to format strings. Not only are they more readable, more concise, and less prone to error than other ways of formatting, but they are also faster! By the end of this article, you will learn how and why to start using f-strings today.

What is %p format string?

%p expects the argument to be of type (void *) and prints out the address. Whereas %x converts an unsigned int to unsigned hexadecimal and prints out the result.

How do you use sprintf strings?

Syntax: int sprintf(char *str, const char *string,...); Return: If successful, it returns the total number of characters written excluding null-character appended in the string, in case of failure a negative number is returned .


2 Answers

The C++ way would be to use a std::stringstream object as:

std::stringstream fmt; fmt << a << " " << b << " > " << c; 

The C way would be to use sprintf.

The C way is difficult to get right since:

  • It is type unsafe
  • Requires buffer management

Of course, you may want to fall back on the C way if performance is an issue (imagine you are creating fixed-size million little stringstream objects and then throwing them away).

like image 82
dirkgently Avatar answered Oct 14 '22 13:10

dirkgently


For the sake of completeness, you may use std::stringstream:

#include <iostream> #include <sstream> #include <string>  int main() {     std::string a = "a", b = "b", c = "c";     // apply formatting     std::stringstream s;     s << a << " " << b << " > " << c;     // assign to std::string     std::string str = s.str();     std::cout << str << "\n"; } 

Or (in this case) std::string's very own string concatenation capabilities:

#include <iostream> #include <string>  int main() {     std::string a = "a", b = "b", c = "c";     std::string str = a + " " + b + " > " + c;     std::cout << str << "\n"; } 

For reference:

  • http://en.cppreference.com/w/cpp/string/basic_string/operator+

If you really want to go the C way. Here you are:

#include <iostream> #include <string> #include <vector> #include <cstdio>  int main() {     std::string a = "a", b = "b", c = "c";     const char fmt[] = "%s %s > %s";     // use std::vector for memory management (to avoid memory leaks)     std::vector<char>::size_type size = 256;     std::vector<char> buf;     do {         // use snprintf instead of sprintf (to avoid buffer overflows)         // snprintf returns the required size (without terminating null)         // if buffer is too small initially: loop should run at most twice         buf.resize(size+1);         size = std::snprintf(                 &buf[0], buf.size(),                 fmt, a.c_str(), b.c_str(), c.c_str());     } while (size+1 > buf.size());     // assign to std::string     std::string str(buf.begin(), buf.begin()+size);     std::cout << str << "\n"; } 

For reference:

  • http://en.cppreference.com/w/cpp/io/c/fprintf

Then, there's the Boost Format Library. For the sake of your example:

#include <iostream> #include <string> #include <boost/format.hpp>  int main() {     std::string a = "a", b = "b", c = "c";     // apply format     boost::format fmt = boost::format("%s %s > %s") % a % b % c;      // assign to std::string     std::string str = fmt.str();     std::cout << str << "\n"; } 
like image 29
moooeeeep Avatar answered Oct 14 '22 14:10

moooeeeep