Question

I've got a C++ class that's templated on the integer type, e.g.,

template<typename int_type>

Say that somewhere in that class, I'd like to use sscanf for reading some values from a file, e.g.,

int_type num_rows;
fgets( buffer, BUFSIZE, in_file );
sscanf( buffer, "%d", &num_rows);

The format specifier only works correctly if the int_type is the intrinsic int.

Is there a better way of treating the format specifier for general int_type?

Was it helpful?

Solution

Instead of using sscanf() and a format specifier use std::istringstream with operator>>():

if (fgets( buffer, BUFSIZE, in_file ))
{
    std::istringstream in(buffer);
    if (!(in >> num_rows))
    {
        // Handle failure.
    }
}

Replacing the (not shown) FILE* and with a std::ifstream would enable removal of the std::istringstream and just read directly from the std::ifstream instead.

OTHER TIPS

You can just declare fmt in your class and provide explicit values per type in the implementation:

// foo.hpp
template< typename T >
class foo
{
private:
    static const char* fmt;

public:
    void print() const
    {
        T num_rows;
        fgets( buffer, BUFSIZE, in_file );
        sscanf( buffer, fmt, &num_rows);
    }
};

and

// foo.cpp
template<> const char* foo< int >::fmt = "%d";
template<> const char* foo< long >::fmt = "%ld";

You could create template helper class:

template<class int_type>
struct fmt_helper_f{};

template<>
struct fmt_helper_f<int>
{
  static const char * fmt() {return "%d";}
};

template<>
struct fmt_helper_f<float>
{
  static const char * fmt() {return "%f";}
};

Actually you may want to use streams for input and output

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top