fstream is being a meanie

Well I was programming a map manager class to manage maps in my RPG.

It loads how many maps there are in one text file, then it opens another text file and reads the locations of the maps from it. Haven't gotten to test the code, because fstream starts to whine and complain about not being able to access a private member.

This error is usually caused by trying to copy a stream, which I'm clearly not doing. I have no idea how this is happening, but I'm sure it's in my function that loads the maps.

MapManager::Init :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
int MapManager::Init()
{
	init.open("Data/Maps/maps.mapdat");
	if(init != NULL)
	{
		// Load the number of maps that the game needs.
		init >> TotalMaps;
	}

	else
	{
		std::cout << "Failure to load maps.\n";
		system("PAUSE");

		init.close();

		return 1;
	}
	init.close();

	maploc.open("Data/Maps/Maps.maploc");
	if(maploc == NULL)
	{
		std::cout << "Failure to load Maps.maploc\n";

		maploc.close();
		
		return 1;
		system("PAUSE");
	}

	// Vectors for holding the 2 c strings
	std::vector<char*> initfiles;
	std::vector<char*> mapfiles;

	char* temp = NULL;

	for(int m = 0; m < TotalMaps; m++)
	{
		maploc >> temp;

		// Add the temporary variable to the vector, then do the same
		// for the other vector.
		initfiles.push_back(temp);

		maploc >> temp;
		mapfiles.push_back(temp);

	}

	maploc.close();

	// Go into a for loop which loads the correct amount of maps from the init file.

	for(int m = 0; m < TotalMaps; m++)
	{

		if(maps[m].Init(initfiles[m], mapfiles[m]) == 1)
		{
			std::cout << "Failed to initialize map(s)\n";
			system("PAUSE");
		}

		if(maps[m].InitTiles() == 1)
		{
			std::cout << "Failed to initialize map tiles.\n";
			system("PAUSE");
		}
	}

	return 0;
}


Sorry to just post like 70 lines of code, but I honestly have no idea where this is coming from. Hopefully you guys could help me. If you need more code I can give it to you.
A private member of MapManager? What line do you get the error?

When you do this: maploc >> temp; temp has to point to a char array that is big enough to hold all the characters in the word. Why don't you use std::string?
Because whenever I do it always throws an error saying that no operator matches these operands.

Peter here's my error message.

http://prntscr.com/1ddzi1
Last edited on
What types are init and maploc, and why are they not defined inside the Init() function?
To check if a stream is open you use ifstream::is_open(). You compare with NULL if you use FILE*.
I think comparing a fstream with NULL calls operator==(int).
Last edited on
It would appear on lines 36 to 51 that you are attempting to read pointer values from a file. [Edit: My bad. You're actually trying to read c strings into memory at an invalid memory address.]

Don't store pointers in a file. Store the data pointed at.

As for your error, you might consider (if the compiler is complaining about not being able to access a variable) supplying what variable, exactly, it is complaining about and also supplying the context in which said variable is defined. You might also consider supplying the compiler error message.

(Another thing you might do is review the sticky on how to ask questions.)

I would say almost all of the variables used in your function should be local to the function, maploc and init in particular. Do you have a compelling reason for them not to be?

Last edited on
std::ifstreams.

Here is the class code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include "Map.h" // Include the map header

// Header guards
#ifndef _MAPMANG_H_
#define _MAPMANG_H_

class MapManager
{
	public:
		int Init();

		std::string getMapName() {return maps[SelectedMap].getName();} // Recives the current map's name
		
		int Update()
		{
			maps[SelectedMap].UpdateTiles();
		}

		bool TouchSolid(SDL_Rect entity)
		{
			maps[SelectedMap].TouchSolid(entity);
		}

		void Render(SDL_Surface* Dest)
		{
			maps[SelectedMap].Render(Dest);
		}

		void RenderT(SDL_Surface* Dest)
		{
			maps[SelectedMap].Render(Dest);
		}

		void Cleanup()
		{
			// Go into a for loop that calls the Cleanup
			// function for all the maps.
			for(int m = 0; m < maps.size(); m++)
			{
				maps[m].Cleanup();
			}
		}

		Map getCurrentMap() const{return maps[SelectedMap];}
		int SelectedMap; // A public variable used to easily change the map
		                 // according to the map's position in the vector.
	private:
		int TotalMaps;
		std::vector<Map> maps; // A vector that will be used as a dynamic
		                       // array which loads maps.

		std::ifstream init;   // For the init file
		std::ifstream maploc; // For the file that holds map locations.
};

#endif//_MAPMANG_H_ 


(Nevermind the string error thing, it seems to be working now.)

No, I don't have a reason for them not being in a local file.

I changed them to class variables for a reason I cannot exactly remember...
Last edited on
Updated the init function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
int MapManager::Init()
{
	std::ifstream init;   // For the init file
	std::ifstream maploc; // For the file that holds map locations.

	// Vectors for holding the 2 strings
	std::vector<std::string> initfiles;
	std::vector<std::string> mapfiles;

	// Temporary string for reading strings from files, then pushing it into a vector.
	std::string temp;

	init.open("Data/Maps/maps.mapdat");
	if(init != NULL)
	{
		// Load the number of maps that the game needs.
		init >> TotalMaps;
	}

	else
	{
		std::cout << "Failure to load maps.\n";
		system("PAUSE");

		init.close();

		return 1;
	}
	init.close();

	maploc.open("Data/Maps/Maps.maploc");
	if(maploc == NULL)
	{
		std::cout << "Failure to load Maps.maploc\n";

		maploc.close();
		
		return 1;
		system("PAUSE");
	}

	for(int m = 0; m < TotalMaps; m++)
	{
		maploc >> temp;

		// Add the temporary variable to the vector, then do the same
		// for the other vector.
		initfiles.push_back(temp);

		maploc >> temp;
		mapfiles.push_back(temp);

	}

	maploc.close();

	// Go into a for loop which loads the correct amount of maps from the init file.

	for(int m = 0; m < TotalMaps; m++)
	{

		if(maps[m].Init(initfiles[m], mapfiles[m]) == 1)
		{
			std::cout << "Failed to initialize map(s)\n";
			system("PAUSE");
		}

		if(maps[m].InitTiles() == 1)
		{
			std::cout << "Failed to initialize map tiles.\n";
			system("PAUSE");
		}
	}

	return 0;
}
Are you still having the same error? The error message you posted, was that the first error message in the list (scroll up)? I can't make sense of it.
A better photo would be: http://prntscr.com/1de69j

I'm still having the same error.

Copying the output I get this:

  main.cpp
c:\documents and settings\bc\my documents\visual studio 2010\projects\quest for originality\quest for originality\code\tile.h(29): warning C4005: 't_sw_gpath' : macro redefinition
          c:\documents and settings\bc\my documents\visual studio 2010\projects\quest for originality\quest for originality\code\tile.h(26) : see previous definition of 't_sw_gpath'
c:\documents and settings\bc\my documents\visual studio 2010\projects\quest for originality\quest for originality\code\mapmanager.h(38): warning C4018: '<' : signed/unsigned mismatch
c:\program files\microsoft visual studio 10.0\vc\include\fstream(890): error C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' : cannot access private member declared in class 'std::basic_ios<_Elem,_Traits>'
          with
          [
              _Elem=char,
              _Traits=std::char_traits<char>
          ]
          c:\program files\microsoft visual studio 10.0\vc\include\ios(176) : see declaration of 'std::basic_ios<_Elem,_Traits>::basic_ios'
          with
          [
              _Elem=char,
              _Traits=std::char_traits<char>
          ]
          This diagnostic occurred in the compiler generated function 'std::basic_ifstream<_Elem,_Traits>::basic_ifstream(const std::basic_ifstream<_Elem,_Traits> &)'
          with
          [
              _Elem=char,
              _Traits=std::char_traits<char>
          ]
  QFO.cpp
c:\documents and settings\bc\my documents\visual studio 2010\projects\quest for originality\quest for originality\code\tile.h(29): warning C4005: 't_sw_gpath' : macro redefinition
          c:\documents and settings\bc\my documents\visual studio 2010\projects\quest for originality\quest for originality\code\tile.h(26) : see previous definition of 't_sw_gpath'
c:\documents and settings\bc\my documents\visual studio 2010\projects\quest for originality\quest for originality\code\mapmanager.h(38): warning C4018: '<' : signed/unsigned mismatch
c:\program files\microsoft visual studio 10.0\vc\include\fstream(890): error C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' : cannot access private member declared in class 'std::basic_ios<_Elem,_Traits>'
          with
          [
              _Elem=char,
              _Traits=std::char_traits<char>
          ]
          c:\program files\microsoft visual studio 10.0\vc\include\ios(176) : see declaration of 'std::basic_ios<_Elem,_Traits>::basic_ios'
          with
          [
              _Elem=char,
              _Traits=std::char_traits<char>
          ]
          This diagnostic occurred in the compiler generated function 'std::basic_ifstream<_Elem,_Traits>::basic_ifstream(const std::basic_ifstream<_Elem,_Traits> &)'
          with
          [
              _Elem=char,
              _Traits=std::char_traits<char>
          ]
c:\documents and settings\bc\my documents\visual studio 2010\projects\quest for originality\quest for originality\code\qfo.cpp(23): warning C4244: 'initializing' : conversion from 'float' to 'Uint32', possible loss of data
  MapManager.cpp
c:\documents and settings\bc\my documents\visual studio 2010\projects\quest for originality\quest for originality\code\tile.h(29): warning C4005: 't_sw_gpath' : macro redefinition
          c:\documents and settings\bc\my documents\visual studio 2010\projects\quest for originality\quest for originality\code\tile.h(26) : see previous definition of 't_sw_gpath'
c:\documents and settings\bc\my documents\visual studio 2010\projects\quest for originality\quest for originality\code\mapmanager.h(38): warning C4018: '<' : signed/unsigned mismatch
c:\program files\microsoft visual studio 10.0\vc\include\fstream(890): error C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' : cannot access private member declared in class 'std::basic_ios<_Elem,_Traits>'
          with
          [
              _Elem=char,
              _Traits=std::char_traits<char>
          ]
          c:\program files\microsoft visual studio 10.0\vc\include\ios(176) : see declaration of 'std::basic_ios<_Elem,_Traits>::basic_ios'
          with
          [
              _Elem=char,
              _Traits=std::char_traits<char>
          ]
          This diagnostic occurred in the compiler generated function 'std::basic_ifstream<_Elem,_Traits>::basic_ifstream(const std::basic_ifstream<_Elem,_Traits> &)'
          with
          [
              _Elem=char,
              _Traits=std::char_traits<char>
          ]
  Generating Code...
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

'init' and 'maploc' should not be members of the MapManager class.

What I suspect is that you are trying to copy or assign a MapManager object, which in turn is trying to copy/assign those ifstreams. Since ifstreams cannot be copied or assigned, you get that error.

Get rid of lines 52 and 53 of your mapmanager.h
I've already done that.

I'm not copying the class, I made one mapmanager class and that's it.

Here's a pastebin link to the only pieces of code in my project that use the mapmanager:

http://pastebin.com/W4Xqdzi3
Last edited on
Is this the only code that uses fstream?

EDIT:

Actually it looks like the same error is occurring in multiple cpp files so the problem is probably in one of your headers. Do you have some kind of common header file that all these source files are including?

EDIT2:

Just saw your pastebin. Looks like QFO.h is the common header.

But I don't see where <fstream> is included. Is that in one of your other headers? Can you post that one?
Last edited on
It's included it map.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include "Tile.h"
#include <SDL_ttf.h>
#include <vector>
#include <fstream>

#ifndef _MAP_H_
#define _MAP_H_

class Map
{
	public:
		int Init(std::string initfile, std::string mapfile);
		int InitTiles();
		int UpdateTiles();

		bool TouchSolid(SDL_Rect entity);

		void Render(SDL_Surface* Dest);
		void RenderT(SDL_Surface* Dest);

		void Cleanup();

		int getMapW()         const{return MapW;}
		int getMapH()         const{return MapH;}
		
		std::string getName() const{return Name;}

	private:
		std::ifstream map;
		std::ifstream mapinitfile;

		std::string s_mapfile;

		std::string Name;
		int MaxTiles;

		SDL_Surface* nameDisplay;
		SDL_Rect window[2];
		TTF_Font* Font;
		SDL_Color Black;

		int MapW;
		int MapH;

		SDL_Surface* Tileset;

		// A vector of tiles
		std::vector<Tile*> Tiles;
};

#endif//_MAP_H_ 


Before the mapmanager class I had no problems whatsoever with my code.
Last edited on
Yep.. There's the problem.

Map owns 'map' and 'mapinitfile'.... two ifstream objects.

You then have a vector<Map> in your map manager.

vector copies its elements. Therefore you are copying Maps, which means you are attempting to copy ifstreams, which you can't do.
Damn. So how can I get around this?
Don't make your ifstreams a member of your class. There's no need for them to be.

You should probably be opening/closing the file in the same routine. The only reason you'd need a lasting ifstream member is if you want the file to remain open for the lifetime of the Map, which is crazy.
I was just about to edit my post and say this :P

Thanks for your help Disch. :)
Topic archived. No new replies allowed.