In load()
, you keep appending more lines to your stringstream ss
but its eof flag is probably remaining set from the previous time through the loop, so even though there's more to read from it, eof is already set so it won't continue providing data via operator>>()
. If you simply call ss.clear()
at the top of the for()
loop, you'll start with an empty stringstream
on each loop, and I think you'll get what you want.
File Storage and Retrieval
Question
I am a high school student programming as a hobby. I make free stuff and I am working on a game using opengl. I need to save and load data but when met with difficulty I made the following to test my methods.
The save file 'shiptest' is correct but when I open the second file 'shipout' which is created with the save data from 'shiptest' only the first line is there. At first I thought that my array wasn't loading any new data and the clear function wasn't getting rid of the first elements. I corrected this assumption by overwriting those lines after saving the data and observing that the saved lines were loaded after all. My new assumption is that the getline func is only getting the first line each time it's called; but i do not know how to fix this.
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <stdio.h>
#include <stdlib.h>
unsigned short int shipPart;
float editShip[256][3];//part ID, x relative, y relative, r,g,b
float activeShip[256][3];
void CLEAR(bool edit)
{
for (int n = 0; n < 256; n++)
{
if (edit)
editShip[n][0] = -1;
else
activeShip[n][0] = -1;
}
}
void saveEdit(std::string name)
{
std::ofstream out;
out.open ("ship" + name + ".txt", std::ofstream::out);
for (int n = 0; n < 256; n++)
{
for (int i = 0; i < 3; i++)
{
if (editShip[n][0] == -1)
break;
out << editShip[n][i] << " ";
}
out << "\n";
}
out.close();
}
void load(std::string name, bool edit)
{
CLEAR(edit);
std::ifstream in;
in.open ("ship" + name + ".txt", std::ifstream::in);
std::string line, buf;
std::stringstream ss;
int i;
for (int n = 0; n < 3; n++)
{
getline(in, line);
ss << line;
i=0;
while (ss >> buf)
{
if (edit)
editShip[n][i] = atof(buf.c_str());
else
activeShip[n][i] = atof(buf.c_str());
i++;
}
}
in.close();
}
int main()
{
for (int n = 0; n < 256; n++)
{
editShip[n][0] = -1;
activeShip[n][0] = -1;
}
editShip[0][0] = 5;
editShip[0][1] = .11;
editShip[0][2] = .22;
editShip[1][0] = 4;
editShip[1][1] = .33;
editShip[1][2] = .44;
editShip[2][0] = 3;
editShip[2][1] = .55;
editShip[2][2] = .66;
saveEdit("test");
editShip[0][0] = 5000;
editShip[0][1] = 8978;
editShip[0][2] = 8888;
load("test",1);
saveEdit("out");
std::cout << "Hello world!" << std::endl;
return 0;
}
Solution
OTHER TIPS
In your load()
function:
for (int n = 0; n < 3; n++)
{
ss.clear(); //< Clear ss here before you use it!
getline(in, line);
ss << line;
i=0;
while (ss >> buf)
{
if (edit)
editShip[n][i] = atof(buf.c_str());
else
activeShip[n][i] = atof(buf.c_str());
i++;
}
}
Getline()
was working just fine. Just clear the stringstream before you use it and you're good to go. Ran this code on my computer and it works as desired.
EDIT: Ack! Just saw that phonetagger said the same thing while I was making my answer. He deserves the +1's not me.