std namespace have something analogous to sscanf?

Started by
16 comments, last by bubu LV 15 years, 12 months ago
Is there a method in the std namespace analogous to sscanf that performs input based on a passed-in arguement? What I'd like to avoid is creating an std object that allocates memory every time I want to parse something from a memory buffer. Example:

// Without std:
bool Parse(const char * Value, float & Size, bool & Relative)
{
    Relative = ( Value[strlen(Value) - 1] == '%' );
    return ( sscanf(Value, "%d", &Size) == 1 );
}

// With std:
bool Parse(const char * Value, float & Size, bool & Relative)
{
    std::stringstream temp(Value);
    temp.seekg(1, std::ios_base::end);
    Relative = ( temp.peek() == '%' );
    temp.seekg(0, std::ios_base::beg);
    temp >> Size;
    return ( temp.good() );
}

In the latter example, I'm assuming the stringstream constructor allocates memory and copies the data, which like I said is what I'm trying to avoid.
Advertisement
Quote:Original post by jorgander
In the latter example, I'm assuming the stringstream constructor allocates memory and copies the data, which like I said is what I'm trying to avoid.

In the former example you're assuming that sscanf() doesn't allocate and copy. Hmm, is micromanaging library code really going to net you that big bonus come payday?

Stephen M. Webb
Professional Free Software Developer

sscanf() is in namespace std if you include the cstdio header.
That is correct, I do not know what sscanf does behind the scenes either, but I think it's safe to say that the std version *does* copy the data. The only way I can be sure is to roll my own, which I'd rather not do for simple stuff like this.

As to your second point, no this is not for pay, it's my own personal work. And it's for stuff like reading data from a file, such as a 3D model file, that could contain hundreds of thousands of values.

It's a simple question, really: Does std have support for non-OO stuff like this, or some way that its objects won't copy data during construction, just retain a pointer to it? In my example, would passing std::ios_base::in as the second constructor parameter (specifying the stringstream as read-only afaik) still result in it being copied?
Quote:Original post by SiCrane
sscanf() is in namespace std if you include the cstdio header.


I chose sscanf as an example because I do actually have a function like the example I gave. I should have been more descriptive in the first post, but I didn't want to write a book just to ask it. My question is more generally, do std objects/methods always copy data? In the simplest case of determining if two char *'s are equal:

regular strcmp: strcmp(first, second) == 0
std string: std::string(first).compare(second) == 0

strcmp() probably does not copy anything, where as std::string probably makes a copy during construction.
strcmp() is also in namespace std if you include the cstring header.
Quote:Original post by jorgander
My question is more generally, do std objects/methods always copy data? In the simplest case of determining if two char *'s are equal:

regular strcmp: strcmp(first, second) == 0
std string: std::string(first).compare(second) == 0

strcmp() probably does not copy anything, where as std::string probably makes a copy during construction.

Why would std::string.compare() copy data? The only time that a std::string should copy data is on assignment - which comparing doesn't involve.

Now if you are comparing two string constants, then yes, you must construct the strings before comparing them, but if you already have two std::strings, comparing them is going to do exactly the same thing as strcmp.

Also don't lose sight of the fact that a std::string is (at a very basic level), little more than an object-oriented wrapper around a C character buffer. Most operations (with the exception of constructing from string literals), will have basically the same implementations.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

If sscanf is suitable for your needs, why not use it? It is part of the standard library.

As to strcmp versus string::compare, this looks a little stupid. Naturally the string version would create two temporary strings, so you get the same complexity + overhead of creating temporary strings.

However, if you used strings in the first place, there would be no additional strings needed to perform a ==. And the latter can potentially be more efficient than strcmp, because it can start by checking if the strings are the same length in the first place.
Quote:Original post by SiCrane
strcmp() is also in namespace std if you include the cstring header.


Hehe, I used strcmp as an example to get my point across. And although I guess I would ask about it too, I was wondering more about formatted i/o. And by "in the std namespace" I suppose I meant a class derived from std::istream or something along those lines. Perhaps I need to do a bit more research before I ask more. Anyway, thanks for the replies.
Quote:Original post by jorgander
Is there a method in the std namespace analogous to sscanf that performs input based on a passed-in arguement? What I'd like to avoid is creating an std object that allocates memory every time I want to parse something from a memory buffer. Example:

*** Source Snippet Removed ***

In the latter example, I'm assuming the stringstream constructor allocates memory and copies the data, which like I said is what I'm trying to avoid.


Good grief! Use a stringstream and get on with life :)

Is stringstream or string copying showing up in your profiling? I'm guessing not. Write the clearest code possible for starters. Make it whacky and unsafe only when it needs to be made whacky and unsafe.

There used to be a class called strstream, which allowed you to manage your own memory. But it was so daft that the standards committee thankfully decided to deprecate it.

This topic is closed to new replies.

Advertisement