1

(I apologize if this is a dumb question; I'm really new to this and don't have much experience with binary files yet)

I'm trying to make a sort of poor-man's MS paint program where you can draw shapes with your mouse, change colors, brush, ect. I need to be able to save the user's progress into a binary file (homework requirements) by means of a struct.

I think I've managed to save the data successfully(?), but I can't seem to extract it back out again -- or at least, I'm having trouble figuring out how to check whether or not there's already anything in the file. No matter how I write it, the compiler doesn't seem interested in reading it in.

Honestly, I might have just gotten myself twisted up with the pointers

If I get rid of the 'while' in front of "inFile.read(reinterpret_cast(&temp), sizeof(ShapeData))" in order to force it to read from the file, it just (not all too surprisingly) returns garbage.

I've written out a 'bug-test' version of it (getting rid of unrelated functions) to try and isolate the problem as much as I can, but I've been at it for hours and could really use the advice of someone who actually fully knows what they're doing. :)

#include <iostream>
#include <fstream>
using namespace std;
#include <SFML\Graphics.hpp>
using namespace sf;

enum ShapeEnum { CIRCLE, SQUARE };

struct ShapeData
{
    ShapeEnum shapeType;
    int shapeLocationX,
    shapeLocationY,     // location x and y originally vector2f;
    shapeColor;         // had more luck with changing to ints for file
                        // (shape color also converted from .tointeger())
};

int main()
{

  int amountFilled = 0;
  ShapeData temp;

  vector<ShapeData*> shapes;

  ofstream oFile;
  oFile.open("shapes.bin", ios::out | ios::binary);
  ifstream inFile;
  inFile.open("shapes.bin", ios::in | ios::binary);

  if (!inFile)
    {
       cout << "file Open Failure" << endl;
       EXIT_FAILURE;
    }

  while (inFile.read(reinterpret_cast<char*>(&temp), sizeof(ShapeData)))
  {
     shapes.push_back(new ShapeData(temp));
     amountFilled++;
  }

     // test input
        temp.shapeColor = Color::Blue.toInteger();
        temp.shapeLocationX = 200;
        temp.shapeLocationY = 400;
        temp.shapeType = CIRCLE;
        shapes.push_back(new ShapeData(temp));
        amountFilled++;
     // test input
        temp.shapeColor = Color::Red.toInteger();
        temp.shapeLocationX = 25;
        temp.shapeLocationY = 650;
        temp.shapeType = SQUARE;
        shapes.push_back(new ShapeData(temp));
        amountFilled++; 

  for (int i = 0; i < amountFilled; i++) // test display
  {
     cout << "Color # : " << shapes[i]->shapeColor << "; " 
     << "Location : ( " 
         << shapes[i]->shapeLocationX << ", " << shapes[i]->shapeLocationY 
         << " ); " 
     << "Enum # : " << shapes[i]->shapeType << endl;

     oFile.write(reinterpret_cast<char*>(&shapes[i]), sizeof(ShapeData));
  }

        oFile.close();
        inFile.close();

    return 0;
}

the way that it's currently written, the output looks like this :

Color # : 65535; Location : ( 200, 400 ); Enum # : 0

Color # : -16776961; Location : ( 25, 650 ); Enum # : 1

When I remove the lines that add in new shapes to the vector, it doesn't put anything into the vector or display at all; I need to figure out how to add what was already in the file in addition to new shapes.

Lee
  • 15
  • 4
  • You most likely do not want to open the outfile before you have read the infile. You're erasing the data before you read it. https://stackoverflow.com/questions/39256916/does-stdofstream-truncate-or-append-by-default – Retired Ninja Apr 05 '19 at 05:16
  • @RetiredNinja Thank you! It's reading from the file now. That was easy. Unfortunately, the actual data is getting scrambled somewhere along the way and not coming out with the same numbers that that I started with, **but** the fact that *that's* working at least is a huge relief. Thanks! – Lee Apr 05 '19 at 05:25
  • There's nothing exciting in your struct. You might consider having a vector of structs rather than a vector of struct pointers. This is probably writing garbage. `reinterpret_cast(&shapes[i]),` because `shapes[i]` is a pointer, and the & makes it a pointer to pointer. Try without the & or with it after you make the vector hold structs instead of pointers. – Retired Ninja Apr 05 '19 at 05:54
  • @RetiredNinja That's excellent advice. Thank you, again! I really appreciate it. That sorted it all out; It's working perfectly now. (phew) – Lee Apr 05 '19 at 06:00

0 Answers0