What is the C++ version of sscanf?

Started by
12 comments, last by cache_hit 14 years, 3 months ago
Hi mates! What is the C++ version of sscanf? Thanks.
I've seen things you people wouldn't believe. Attack ships on fire off the shoulder of Orion. I watched C-beams glitter in the dark near the Tannhauser gate. All those moments will be lost in time, like tears in rain. Time to die.
Advertisement
sscanf can be used in c++ just fine. So can virtually all functions available in c
Shoot Pixels Not People
Use std::istringstream. You can check an example here.
Quote:Original post by fcoelho
Use std::istringstream. You can check an example here.


I'll take type safe, type checked (at compile-time) format strings over current C++ streams any day. Lets just hope that C++0x generalizes the ability to analyze string literals at compile-time with constexpr functions (only currently possible with constexpr user-defined literals) and variadic templates.
Quote:Original post by snk_kid
I'll take type safe, type checked (at compile-time) format strings over current C++ streams any day.
What are you talking about? Printf certainly has a nice little domain language going, and though I occasionally wish for positional arguments and user-defined types as standard features I must admit that it covers my day-to-day needs admirably.
Scanf, on the other hand, is virtually useless for anything but the most rudimentary and sloppy type of parsing. As soon as you need any sort of error handling or try to read anything more complicated than space-separated set of integers you end up with convoluted formats with silent arguments, bizarre %[...] catchalls, and length limit parameters (naturally sent as integers rather than size_t just trip up unwary users) for every string. Also, someone needs to be shot for making %f a float type rather than a double.

Not that istreams are all that much better but at least there aren't quite as many ways to mess up with standard streams.
istringstream makes useless copies of the string, allocates memory often when it's not necessary. And it is not so simple to use it.
I'd suggest using C string functions here because they also help to develop bug seeking skills. ^_^
Quote:Original post by implicit
What are you talking about? Printf certainly has a nice little domain language going, and though I occasionally wish for positional arguments and user-defined types as standard features I must admit that it covers my day-to-day needs admirably.


I'm talking about something that doesn't currently exist in C/C++ in an ideal form (yes I already know about GCC doing some form of compile-time type checking and there is boost.format, don't even go there).

In OCaml/F# format strings are analyzed by the compiler at compile-time and gives you a function type from the given format, this is given to a parametric type typically called format/Format. This is used with their standard library IO functions and if you apply these functions with arguments with the wrong type(s) and/or the wrong number of arguments you will get a compile-time error. You can use this special format type in your own functions.

As I've already stated in C++0x a "variadic template constexpr user-defined literal" (effectively a operator overload templated over an infinite sequence of characters (variadic template with non-type parameters) for which you can use a string literal to implicitly instantiate the template.

This is the only ideal way to analyze string(s) (literals) at compile-time in C++0x. It's stupid to limit this functionality to only user-defined literals, this should be applicable to any constexpr function.

The ability to analyze strings at compile-time is not just nice for format strings so why not give us the ability to achieve it in a more flexible way instead of the restricted way in the current working draft of C++0x.

My point is that while format strings kind of suck in C/C++, this does not mean the idea sucks in general in fact they are done very well in more type-safe languages.

Quote:Original post by implicit
Scanf, on the other hand, is virtually useless for anything but the most rudimentary and sloppy type of parsing.


Something similar can be said for C++ I/O streams. If you're going to parse something complicated then you should be using regular expressions library and if they are not suitable then you should be using a lexer/parser framework.

Quote:Original post by implicit
As soon as you need any sort of error handling or try to read anything more complicated than space-separated set of integers you end up with convoluted formats with silent arguments, bizarre %[...] catchalls, and length limit parameters (naturally sent as integers rather than size_t just trip up unwary users) for every string. Also, someone needs to be shot for making %f a float type rather than a double.


That is an issue specifically with C/C++ (something that could easily be rectified in C++0x with variadic templates and constexpr functions or an alternate method). This is not a problem with the idea of format strings in general.

[Edited by - snk_kid on December 26, 2009 7:38:53 AM]
Quote:Original post by snk_kid
...
Okay, I'll buy that. I got the impression that you thought that scanf with compile-time checking in GCC or extended with type-safety as-is to C++ was a useful way of doing parsing, but perhaps there is a library or language out there which has managed to do parsing with vaguely scanf-like templates in a reasonable way.

It's just that I've spent way too much time trying to get scanf to work in the past, and as soon as you need any sort of error detection it just doesn't work. Simply trying to figure out whether you've matched the whole line with sscanf is almost enough to give me a migraine.
Quote:Original post by implicit
Quote:Original post by snk_kid
...
Okay, I'll buy that. I got the impression that you thought that scanf with compile-time checking in GCC or extended with type-safety as-is to C++ was a useful way of doing parsing, but perhaps there is a library or language out there which has managed to do parsing with vaguely scanf-like templates in a reasonable way.


For C++ Boost.Format gets you some way there but as far as I know it only works with output streams and I would probably get into trouble using it at work on a large project. Got to write & use lowest common denominator C++ code at work on large projects with lots of coders.
Quote:Original post by fcoelho
Use std::istringstream. You can check an example here.


Thanks a lot. I will try it right now.
I forgot to say I use std::string, never char.
I know I can use my_string.c_str() but I prefer to use a STL approach.

Thanks.
I've seen things you people wouldn't believe. Attack ships on fire off the shoulder of Orion. I watched C-beams glitter in the dark near the Tannhauser gate. All those moments will be lost in time, like tears in rain. Time to die.

This topic is closed to new replies.

Advertisement