Search code examples
c++stringtimecastingtimeval

timeval to string (converting between the two)


I'm trying to pull the two components out of a timeval struct and place them into strings.

I'm not having much luck with this. I've attempted casting and converting first to a long and then to a string. I need the most efficient way to do this.

Any ideas? I do NOT want to convert to another data structure first (localtime, etc). I need the seconds and the microseconds in their original state.

EDIT: I know stringstream is an option here -- I'm just not sure how efficient that is. Every microsecond counts here, so I'm looking for the fastest implementation.


Solution

  • Boost's lexical_cast should be reasonably fast.

    Edit:
    Let me elaborate. Here's an example of its usage:

    std::string strSeconds = lexical_cast<std::string>(time.tv_sec);
    std::string strMicroSec = lexical_cast<std::string>(time.tv_usec);
    

    For more complicated string formatting, the Boost documentation recommends the basic std::stringstream. Something like:

    std::stringstream ss;
    ss << time.tv_sec << " seconds, " << (time.tv_usec/1000L) << " milliseconds";
    return ss.str();
    

    Reasonably fast, readable, safe and standard. You might be able to get a little more speed by using sprintf from the cstdio header. (preferably sprintf_s if available) There's no explicit support for long variables in printf, but these days on 32-bit+ machines they're usually the same size so you can use the %d specifier to handle them:

    std::string tvtostr(timeval time) {
        // unless corrupted, the number of microseconds is always less than 1 second
        assert(time.tv_sec >= 0 && time.tv_usec >= 0 && time.tv_usec < 1000000000L);
        static_assert(sizeof(long)==4 && sizeof(int)==sizeof(long), 
            "assuming 32 bit ints and longs" ); 
    
        // space for one unbounded positive long, one long from 0 to 999,
        // the string literal below, and a '\0' string terminator
        boost::array<CHAR, 10+3+23+1> buffer; 
    
        sprintf_s(buffer.data(), buffer.size(), "%d seconds, %d milliseconds", 
            time.tv_sec, (time.tv_usec/1000L) );
    
        return buffer.data();
    }