7
string whatTime(int seconds) {

 string h,m,s,ans;
 stringstream ss;

 ss << (seconds/3600); 
 seconds -= (3600*(seconds/3600));
 ss >> h;
 ss.str("");

 ss << (seconds/60);
 seconds -= (60*(seconds/60));
 ss >> m;
 ss.str("");

 ss << seconds;
 ss >> s;


 return (h + ":" + m + ":" + s );

}

Output for above program is coming in this format "some_value::" I have also tried ss.str(std::string()) and ss.str().clear() but even that doesn't work. Could somebody please suggest any ways how to tackle this problem?

Rishabh
  • 730
  • 2
  • 11
  • 25
  • Did you try to first fill it and after read it? Because now you fill then read ... Try fill fill fill, read read read. No clear needed. – fonZ Dec 15 '12 at 11:47

3 Answers3

14

You've correctly emptied the string buffer with ss.str(""), but you also need to clear the stream's error state with ss.clear(), otherwise no further reads will be attemped after the first extraction, which led to an EOF condition.

So:

string whatTime(int seconds) {

 string h,m,s,ans;
 stringstream ss;

 ss << (seconds/3600); 
 seconds -= (3600*(seconds/3600));
 ss >> h;
 ss.str("");
 ss.clear();

 ss << (seconds/60);
 seconds -= (60*(seconds/60));
 ss >> m;
 ss.str("");
 ss.clear();

 ss << seconds;
 ss >> s;


 return (h + ":" + m + ":" + s );

}

However, if this is your full code and you do not need the individual variables for any reason, I'd do this:

std::string whatTime(const int seconds_n)
{
    std::stringstream ss;

    const int hours   = seconds_n / 3600;
    const int minutes = (seconds_n / 60) % 60;
    const int seconds = seconds_n % 60;

    ss << std::setfill('0');
    ss << std::setw(2) << hours << ':'
       << std::setw(2) << minutes << ':'
       << std::setw(2) << seconds;

    return ss.str();
}

It's much simpler. See it working here.

In C++11 you can avoid the stream altogether using std::to_string, but that doesn't allow you to zero-pad.

Community
  • 1
  • 1
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
2

You need to call the clear method of the stringstream rather than on the string returned by the stringstream using ss.clear().

string whatTime(int seconds) {

 string h,m,s,ans;
 stringstream ss;

 ss << (seconds/3600); 
 seconds -= (3600*(seconds/3600));
 ss >> h;
 ss.str("");
 ss.clear();

 ss << (seconds/60);
 seconds -= (60*(seconds/60));
 ss >> m;
 ss.str("");
 ss.clear();

 ss << seconds;
 ss >> s;


 return (h + ":" + m + ":" + s );

}
ctor
  • 5,938
  • 2
  • 26
  • 37
  • thanks, could you please tell why it's necessary to use ss.clear() and why I was getting an empty string? – Rishabh Dec 15 '12 at 11:54
  • @rishabh, It's necessary because you want to clear the stringstream itself. The methods you called `ss.str().clear()` was clearing an object of type string that was returned by the stringstream. – ctor Dec 15 '12 at 11:56
  • When you read the entire contents of the stream, like in `ss >> h;`, you have also reached EOF for the stream. That state sticks until you clear it. – Bo Persson Dec 15 '12 at 11:57
  • No. `ss.clear()` clears the stream's _error_ bits. `ss.str("")` is the correct way to empty the buffer. You should use _both_. – Lightness Races in Orbit Dec 15 '12 at 11:57
  • @ctor: `ss.str("")` does nothing on anything "returned by" the stringstream - [it sets the value of the internal string buffer](http://en.cppreference.com/w/cpp/io/basic_stringstream/str). – Lightness Races in Orbit Dec 15 '12 at 11:58
  • @LightnessRacesinOrbit, I originally had both `ss.str("")` in but someone edited it removing them stating they were not necessary. Also, ss.str() returns a std::string object in reference to it's use in this call `ss.str().clear()`. – ctor Dec 15 '12 at 12:01
  • @ctor: The OP's code says `ss.str("")`, and it _is_ necessary. – Lightness Races in Orbit Dec 15 '12 at 12:03
  • @LightnessRacesinOrbit, Yeah I originally posted my answer with them left in as I thought they were required but someone removed them in an edit. – ctor Dec 15 '12 at 12:04
  • @dasblinkenlights: Please don't make such fundamental changes to people's answers, _especially_ when [those changes are incorrect](http://stackoverflow.com/a/2848109/560648). Thanks. – Lightness Races in Orbit Dec 15 '12 at 12:07
0

You only need the stringstream, nothing else. All the rest is pure overhead.

string whatTime(int seconds) {
    stringstream ss;

    ss << setFill('0');
    ss << setw(2) << (seconds/3600) << ":"         // hours
       << setw(2) << ((seconds / 60) % 60) << ":"  // minutes
       << setw(2) << (seconds%60);                 // seconds

    return ss.str();
}
fonZ
  • 2,428
  • 4
  • 21
  • 40
  • Intermediate `const` variables provide no overhead, yet a significant increase in readability. And, btw, your `whatTime(5)` returns `"0:0:5"` which is ew – Lightness Races in Orbit Dec 15 '12 at 14:00
  • Then you can add std::setw(2) and setfill('0') like you did in your example. And its still readable i think if you put it on different lines because if you talk about time you usually know that there are hours minutes and seconds. – fonZ Dec 15 '12 at 23:31