28

I have a problem that sscanf solves (extracting things from a string). I don't like sscanf though since it's not type-safe and is old and horrible. I want to be clever and use some more modern parts of the C++ standard library. What should I use instead?

Ben Hymers
  • 22,821
  • 15
  • 55
  • 79
  • 11
    For example for the reason he said, that sscanf is not type-safe. – jalf Jun 23 '09 at 15:30
  • 6
    @Kaleb Pederson: For many English speakers, "clever" can just mean "smart" and doesn't have the negative connotation it sometimes has in the US. Note that Ben Hymers is from the UK. – Naaff Jun 23 '09 at 15:30
  • 9
    "Clever" has negative connotations? That probably says something about the US. I'm not sure what though. Yes, I meant smart :) – Ben Hymers Jun 24 '09 at 15:43
  • @BenHymers Come to think of it, yes, in the US "clever" is sometimes used with a touch of irony to mean something along the lines of "creative, but naughty". Self-modifying code is something one might call clever in this way. – Nathan Monteleone Jun 22 '16 at 17:32
  • Yes that's right. Discussing "clever" vs "smart" is far more important :) – Utkarsh Kumar Jun 29 '17 at 07:31

5 Answers5

39

Try std::stringstream:

#include <sstream>

...

std::stringstream s("123 456 789");
int a, b, c;
s >> a >> b >> c;
Fred Larson
  • 56,061
  • 15
  • 106
  • 157
  • 1
    how to know if c is not there, for example the string were "123 456"? – unludo Jul 26 '12 at 14:38
  • @unludo: In that case, `c` would be unmodified. You could initialize `c` with a default value, or you might need more sophisticated parsing. A tokenizer would probably work. – Fred Larson Jul 27 '12 at 03:34
  • 1
    As of C++11, `c` would be reset to `0`, and before that I believe its post-failure value was undefined. Anyway, to check whether `c` is there use the stream state (for convenience, from `operator bool()`): `if (s >> a >> b) if (s >> c ) abc_there(); else ab_there(); else didnt_have_a_and_b();`. – Tony Delroy Mar 25 '16 at 04:02
6

For most jobs standard streams do the job perfectly,

std::string data = "AraK 22 4.0";
std::stringstream convertor(data);
std::string name;
int age;
double gpa;

convertor >> name >> age >> gpa;

if(convertor.fail() == true)
{
    // if the data string is not well-formatted do what ever you want here
}

If you need more powerful tools for more complex parsing, then you could consider Regex or even Spirit from Boost.

AraK
  • 87,541
  • 35
  • 171
  • 230
2

If you include sstream you'll have access to the stringstream classes that provide streams for strings, which is what you need. Roguewave has some good examples on how to use it.

Sebastian Mach
  • 36,158
  • 4
  • 87
  • 126
Kaleb Pederson
  • 43,537
  • 19
  • 96
  • 144
0

If you really want not to use streams (It's good because of readability), you can use StringPrintf.

You can find its implementation in Folly:

https://github.com/facebook/folly/blob/master/folly/String.h#L165

iampat
  • 1,022
  • 1
  • 11
  • 23
  • Nice bit of code (I'm using something almost the same already), though it's a replacement for `printf` rather than `sscanf`. – Ben Hymers Aug 08 '13 at 09:19
-1

fgets or strtol

joe
  • 31,345
  • 29
  • 92
  • 134