JavaCake
JavaCake

Reputation: 4115

Converting dots in double to comma when writing to file

I am working on a small export function where i need to write 1million lines consisting of 6x doubles. Unfortunately the tool that reads the data requires that the dots are replaced with commas. The way i convert them now is by replacing manually in an editor, which is cumbersome and extremely slow for a file that is about 20MB.

Is there a way to do this conversion while writing?

Upvotes: 1

Views: 3329

Answers (2)

James Kanze
James Kanze

Reputation: 153909

Using a tool like tr would be better than doing it manually, and should be your first choice. Otherwise, it's fairly simple to input through a filtering streambuf, which converts all '.' to ',', or even converts only in specific contexts (when the preceding or following character is a digit, for example). Without the context:

class DotsToCommaStreambuf : public std::streambuf
{
    std::streambuf* mySource;
    std::istream* myOwner;
    char myBuffer;
protected:
    int underflow()
    {
        int ch = mySource->sbumpc();
        if ( ch != traits_type::eof() ) {
            myBuffer = ch == '.' ? ',' : ch;
            setg( &myBuffer, &myBuffer, &myBuffer + 1 );
        }
    }
public:
    DotsToCommaStreambuf( std::streambuf* source )
        : mySource( source )
        , myOwner( NULL )
    {
    }
    DotsToCommaStreambuf( std::istream& stream )
        : mySource( stream.rdbuf() )
        , myOwner( &stream )
    {
        myOwner->rdbuf( this );
    }
    ~DotsToCommaStreambuf()
    {
        if ( myOwner != NULL ) {
            myOwner.rdbuf( mySource );
        }
    }
}

Just wrap your input source with this class:

DotsToCommaStreambuf s( myInput );

As long as s is in scope, myInput will convert all '.' that it sees in the input into ','.

EDIT:

I've since seen the comment that you want the change to occur when generating the file, rather than when reading it. The principle is the same, except that the filtering streambuf has an ostream owner, and overrides overflow( int ), rather than underflow. On output, you don't need the local buffer, so it's even simpler:

int overflow( int ch )
{
    return myDest->sputc( ch == '.' ? ',' : ch );
}

Upvotes: 4

Syntactic Fructose
Syntactic Fructose

Reputation: 20076

I would make use of the c++ Algotithm library and use std::replace to get the work done. Read the entire file into a string and call replace:

std::string s = SOME_STR; //SOME_STR represents the set of data 
std::replace( s.begin(), s.end(), '.', ','); // replace all '.' to ','

Upvotes: 0

Related Questions