Question

I'm trying to convert an int to a string via an ostringstream but every time I put data into the stream, it stays in the stream. I've tried using both .flush() and <<endl but the stream never empties. This question suggests I don't really get streams (I don't, still working on that) and what I'm doing is hokum and unnecessary.

int main()
{
  long int max = 0;
  ostringstream strs;
  for(int i=10;i<100; i++){
    for(int j = i; j < 100; j++){ 
        long int product = i*j;
        strs.flush();
        strs <<product;

        string str = strs.str(); 
        cout<<str;
        int size = str.length();
    }
  }
  cout<<max;
  return 0;
}

currently I get an output of

100/100
110/100110
120/100110120
130/100110120130
etc...

instead of

100/100
110/110
120/120
130/130
etc... 
Was it helpful?

Solution

std::ostringstream is a writer interface to a string. Using << appends to the string, and flush is superfluous, since the string does not have a buffer.

To change the string to which the stream writes (such as to an empty one), use the setting version of its str() member function:

strs << product;
string str = strs.str();
strs.str(""); // reset string written into

OTHER TIPS

By far the easiest way to handle this is to create a new stringstream object every time you want it to be empty. In most cases (including yours) this is easily handled by simply letting the existing object go out of scope, and having a new one that's created when you re-enter the correct scope.

Personally, I'd do the job by moving all the code to convert from int to std::string into a function that has a local stringstream object, so a "clean" stringstream is created every time you call the function, and destroyed when you leave it.

std::string to_string(long int in) { 
    std::stringstream buffer; // New/empty every time this function is called
    buffer << in;
    return buffer.str();
}                             // here buffer goes out of scope and is destroyed.

int main()
{
  long int max = 0;
  for(int i=10;i<100; i++){
    for(int j = i; j < 100; j++) {
        long int product = static_cast<long>(i)*j;
        std::string str = to_string(product);

        // presumably:
        // if (product > max) max = product;

        std::cout << str;

        // you never seem to use this:
        //int size = str.length();
    }
  }
  cout<<max;
  return 0;
}

A couple of notes: if your compiler is reasonably recent, it may already have an std::to_string in its standard library, so you can just use that instead of writing your own.

Also note the cast to long before multiplying i and j. Given the values you're using right now, this isn't strictly necessary, but neither is the use of long for product. Assuming you might ever use values where product could be larger than will fit in an int, the cast becomes necessary. Without it, you're doing multiplication on two ints, which naturally produces an int result. Then you're taking that result (which has already overflowed if it's too large to fit in an int) and converting it to long. By converting one of the operands to long before the multiplication, you force the multiplication to be carried out on longs as well, preventing the overflow (at least assuming long is large enough to hold the result).

Put ostringstream into scope, so that it will be recreated each time you enter it. In your case it will be:

int main()
{
  long int max = 0;
  {
  ostringstream strs;
  for(int i=10;i<100; i++){
    for(int j = i; j < 100; j++){ 
        long int product = i*j;
        strs.flush();
        strs <<product;

        string str = strs.str(); 
        cout<<str;
        int size = str.length();
    }
  }
}

  cout<<max;
  return 0;
}

clear the ostringstream.buffer thus:

strs.str("");

To reset an std::ostringstream, you just assign a new buffer:

std::ostringstream oss;
// ...
oss.str(std::string());

However, most of the time that's not necessary since you can define/initialize your stringstream in the narrowest scope possible to get that automatically. In your case, you'll probably want to define it inside the outer for loop.

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