1

I am converting someone else's C++ library to work under GCC (Xcode). What is the basic method for string formatting?

EDIT: I see the original phrasing of my question caused a lot of confusion, not to mention some amusement. What I need to do is replace certain string formatting functions in their library. They have done formatting via wxString, which I don't want to include in my project -- I know it is out there for Xcode, but that seems like a sledgehammer-type approach for the simple formatting I need to do. They have functions which take their objects and spit out strings -- typically (char*), and I need to create the same (char*) outputs [which might then go to another object in the library; not necessarily to the user], but do it in a way that does not use wxString. And I'd rather avoid turning it into C++. In Objective-C, I do this all the time with NSString's stringWithFormat: method. Obviously I don't want to use any NSString methods and don't want to create NSStrings. Creating (char*) or C++ strings would be fine. And no, it's not a false fact, and it's not homework.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
William Jockusch
  • 26,513
  • 49
  • 182
  • 323

4 Answers4

5

You can use streams:

std::stringstream ss;

ss << somedouble << someint;
Tony The Lion
  • 61,704
  • 67
  • 242
  • 415
  • Heheh, beat me to it! :) – Jonathan Sterling Jun 15 '11 at 13:14
  • His format is scientific double (%g). I think your example will do a different conversion. –  Jun 15 '11 at 13:16
  • @Vlad, I guess then he'd have to create custom `operator <<` and `operator >>` overload – Tony The Lion Jun 15 '11 at 13:17
  • 1
    @Tony: I think that is not necessary as there are stream format modifiers like `std::hex` etc. –  Jun 15 '11 at 13:19
  • @phresnel: Right. I am just saying that providing exact equivalent will be much better. Dude doesn't know I/O streams or C++ whatsoever, so... I personally almost never use C++ i/o streams because I have a strong believe that they suck, so I can't throw any examples from top of my head. –  Jun 15 '11 at 13:23
  • @Vlad Lazarenok: Though once you understand the impact of type safety and software security, C-format-strings suck more than iostreams. Also, I fear you must be using them wrong; they are extensible upon your own types, so e.g. you can do "MyAwesomeFoo foo, bar; cout << (foo * bar) << '\n';", which is far less tedious than C-like approaches. – Sebastian Mach Jun 15 '11 at 13:56
2

You can use the printf family of functions, but in 99.99% of cases, this is heavily frowned upon for very good reason.

See Tony The Tiger's answer.


edit: Okay. Why the frowning upon format strings.

  • How do you printf your own types or types from some 3rd party C++ library? Unlike printf, streams are extensible:

    cout << foo << '\n';

    vs

    printf ("%s: %f %f %f / scc(%d)\n", 
     foo.name(), 
     foo.height(), foo.width(), foo.depth(),
     foo.sampleCount());
  • oh crap, passing non-POD types to varargs yields undefined behaviour; guess what foo.name()'s return type is? Funnily, it compiles fine, and depending on the implementation, might even work for some strange reason.

  • After a while, I begin to use my own non-primitive Decimal-implementation, to be used as return-type by foo.width()/height()/depth(). Crappily crap, now I invoke undefined behaviour 4 times in that line alone.

  • How do I avoid format-string redundancy? Shall I externalize printing like this:

printf("foo is:"); 
   printFoo (stdout); 
   printf("\n");
  • lastly, I've had a bad day and a bad night. I type: float f; fscanf(stdout, "%c %f", f); -> Please find all errors.
Sebastian Mach
  • 38,570
  • 8
  • 95
  • 130
  • Frown all you like... I've personally also tried to be good and use ``, but come on, the sheer amount of verbosity to express a simple format that's required at times... if you know what data types you're dealing with, a quick use of `*printf` can be a total lifesaver. – Kerrek SB Jun 15 '11 at 13:25
  • @Kerrek SB: come on ... a) How do you printf your own types or types from some 3rd party C++ library? Unlike printf, streams are extensible: `MyAwesomeFoo foo, bar; cout << foo << '\n';` sucks really more than `printf ("%s: %f %f %f / scc(%d)\n", foo.name(), foo.height(), foo.width(), foo.depth(), foo.sampleCount());`, really? – Sebastian Mach Jun 15 '11 at 14:02
  • @Kerrek SB: b) oh crap, passing non-POD types to varargs yields undefined behaviour; guess what foo.name()'s return type is? Funnily, it even compilers, and depending on the implementation, might even work for some strange reason. – Sebastian Mach Jun 15 '11 at 14:03
  • @Kerrek SB: c) After a while, I begin to use my own non-primitive Decimal-implementation, to be used as return-type by foo.width()/height()/depth(). Crappily crap, now I invoke undefined behaviour 4 times in that line alone. – Sebastian Mach Jun 15 '11 at 14:04
  • @Kerrek SB: d) How do I avoid format-string redundancy? Shall I externalize printing like this: `printf("foo is:"); printFoo (stdout); printf("\n");`. How non-tedious. – Sebastian Mach Jun 15 '11 at 14:05
  • @Kerrek SB: e) lastly, I've had a bad day and a bad night. I type: `float f; scanf("%c %f", f);` ... So yeah, come on. – Sebastian Mach Jun 15 '11 at 14:07
  • @phresnel: It's all situational. Of course there's lots of beauty in overloading your own stream operations. But when you're trying to print out a hex dump of memory content (e.g. while debugging a long double ULP-comparison), I can gladly write printf-%02X-output today for something you'll still be setw/setfill/uppercase/hex-ing tomorrow :-) Situational. (Don't forget to std::dec back, too, at the next unpredictable program flow point!) – Kerrek SB Jun 15 '11 at 14:08
  • @Kerrek SB: Well you wrote printf can be a lifesaver, but actually that breed is among the number one security problems, therefore possibly a killer. Agree on situational, but your quick hexdump is just the 0.01% of use cases, and typically such things are not exposed to end users. – Sebastian Mach Jun 15 '11 at 14:18
  • @phresnet: I guess a steel boot can be a lifesaver to a builder and useless to a fashion model... and I do have a [vested interest](http://stackoverflow.com/questions/4850473/pretty-print-c-stl-containers) in `operator<<`! :-) I just find it curious that formatted printing of simple data types can be such a pain in C++... thanks for updating the post though! – Kerrek SB Jun 15 '11 at 14:27
  • @phresnet: I certainly share no commensurate love for `fscanf`, so don't put that in my mouth :-) – Kerrek SB Jun 15 '11 at 14:29
  • @Kerrek SB: From the formatting standpoint, format strings are all fine and iostreams are not. It is really the security and extensibility that make them suck less :) – Sebastian Mach Jun 15 '11 at 14:31
  • @phresnet: I agree. That's why I had heavily mixed output code in the past, but I'm now sticking to pure C++ iostreams, even though I sometimes fill a screen with a simple debug output code! – Kerrek SB Jun 15 '11 at 14:33
1

sprintf() is a good starting point. However, it really depends on what you wan't to achieve. std::stringstream is a good alternative as Tony The Tiger points out, Boost.Format is another.

larsmoa
  • 12,604
  • 8
  • 62
  • 85
1

There are many ways of doing it in C++. For example:

char str[256];
snprintf (str, sizeof (str), "%g %d %s", someDouble, someInteger, someString);

You can also print directly to some output stream, use C++ I/O streams, even to the degree of Boost.LexicalCast.