1

I am creating a HTML file that creates a Google map of a object called Quake which contains Latitude, Longitude, Magnitude and Depth. Another class called QuakeData is a class that creates a vector of Quake objects.

A function below takes the vector of objects, and gets the details of them (Latitude, Longitude and Magnitude) and then outputs them into the HTML in this format:

[58.678, -151.887, 'M2.6'],

Where the first number is the Latitude, the second is the Longitude, and the third is the Magnitude, in the format shown.

Here is the loop that I currently have, which extracts the Latitude, Longitude and Magnitude using getters:

double mag;
double lat;
double lon;
string complete;
ostringstream out;
vector<Quake>::const_iterator i;
for (i = quakes.begin(); i != quakes.end(); i++)
{
    mag = i->getMagnitude();
    lat = i->getLatitude();
    lon = i->getLongitude();

    out << "[" << lat << ", " << lon << ", 'M" << mag << "'],";
    complete = out.str();
    outfile << complete << endl;
}

However this produces a result like this:

[58.678, -151.887, 'M2.6'], (end of line)
[58.678, -151.887, 'M2.6'],[33.92, -117.08, 'M2.9'],(end of line)
[58.678, -151.887, 'M2.6'],[33.92, -117.08, 'M2.9'],[-3.203, 142.864, 'M4.7'],(end of line)

What I want is:

[58.678, -151.887, 'M2.6'],(end of line)
[33.92, -117.08, 'M2.9'],(end of line)
[-3.203, 142.864, 'M4.7'],(end of line)

What exactly is wrong here? Any help would be greatly appreciated.

Phillip Macdonald
  • 434
  • 1
  • 4
  • 16

4 Answers4

5

Each loop appends new data to the existing stream: move the declaration inside the loop so it's using a new instance for each line.

for (i = quakes.begin(); i != quakes.end(); i++)
{
  ostringstream out;
Steve Townsend
  • 53,498
  • 9
  • 91
  • 140
3

You need to clear your ostringstream between iterations. Use out.str(""); out.clear(); (check here for an explanation).

Community
  • 1
  • 1
Mohammed Hossain
  • 1,319
  • 10
  • 19
1
complete = out.str();
out.str("");
qPCR4vir
  • 3,521
  • 1
  • 22
  • 32
0

As people have pointed out you either need to reset the ostringstream or reduce its scope.

A more idiomatic and efficient way to write your code is to extract the code for outputing a Quake to an ostream, and then use standard algorithms to copy it to your output stream directly, without needing an intermediate ostringstream:

ostream& operator<<(ostream& os, const Quake& quake) {
    os << "["
       << quake.getLatitude() << ", "
       << quake.getLongitude() << ", "
       << "'M" << quake.getMagnitude()
       << "']";
    return os;
}

int main() {
    vector<Quake> quakes;
    ofstream outfile("quakes.txt");

    copy(quakes.begin(), quakes.end()
        ostream_iterator<Quake>(outfile, ",\n"));
}
Peter Wood
  • 23,859
  • 5
  • 60
  • 99