Using strings with ofstream

Hello,

I'm trying to write a roguelike as a way to learn the language. Right now, I'm trying to write a string to a file as part of a save file function. I've been able to figure out most stuff but for some reason this just doesn't want to work for me. It seems like it should be really easy, but I guess I'm just missing something :)

The function that gets called (as it is now) and the definition of class Creature is given below. The basic structure I'm going with now is a save file that includes all the details currently implemented for map tiles (that part works fine) and a list of all the details currently implemented for each creature on the map (this works fine, except for the one line that I am struggling with):

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
int Map::savemap()
{

  ofstream file1 ("save/map.txt");
  ofstream file2 ("save/creatures.txt");
  ofstream file3 ("save/items.txt");
  int monid=0;
  int itemid=0;

  if ( !file1.is_open() || !file2.is_open() || !file3.is_open() ) {return 0;}

  file1 << "seed : " << seed << "\n";

  int i,j;
  for (j=0;j<20;j++) {

    for (i=0;i<80;i++) {

      // Use @'s as delimiters because they won't get                                                                                                                   
      // used as map features                                                                                                                                           

      file1 << "@";

      file1 << map[j][i].symbol << map[j][i].visible;

      file1 << map[j][i].passable << map[j][i].seen;

      file1 << map[j][i].bloody << map[j][i].seethrough;

      file1 << map[j][i].opacity;

      file1 << "@";

      if (map[j][i].creature != NULL) {

        char cname[24];
        Creature * creature = map[j][i].creature;
        string name = creature->getname();
        strcpy(cname,name.c_str());
        //      char * name;                                                                                                                                           
        //cname = new char[24];                                                                                                                                         
        //strcpy(cname, name.c_str());

        file2 << "\n[" << monid++ << "]\n";

        file2 << "[name] ";

        file2 << name.c_str();

        file2 << "\n";

        file2 << "[symb] " << (map[j][i].creature)->getsymb() << "\n";

        file2 << "[x,y] " << (map[j][i].creature)->x << "," << (map[j][i].creature)->y << "\n";

        file2 << "[viewdist] " << (map[j][i].creature)->viewdist << "\n";

      }

           if (map[j][i].ilist != NULL) {                                                                               
// not written yet
    }

    file1 << "\n";

  }

  file1.close();
  file2.close();
  file3.close();

  return 1;

}



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Creature
{
 public:
  Creature(Map *map, int sy, int sx, char ssymb, string sname);
  ~Creature();
  void step(Map *map, int dx, int dy);
  char getsymb();
  string getname();
  int x;
  int y;
  virtual int ai(Map *map, Screen *vscreen);
  int viewdist;
 protected:
  string name;
  char symb;
};


"map" is a 2d array of structures that contain a bunch of stuff, including a pointer to a Creature object. If nothing is there, map[y][x].creature == NULL.

The part that doesn't work properly is "file2 << name.c_str();" name is a string, taken from the Creature object pointed to by map[y][x].creature. I've read strings can't be used directly with ofstream, but doing name.c_str() to pass it a character string instead just outputs nothing on that line. I also tried
"char * cname[name.length() + 1];
strcpy(cname, name.c_str());"
and then file2 << cname, but that also doesn't seem to work properly. I haven't found much useful in my searches. Can someone suggest something else to try or look up? If more information is needed, let me know. I am including <string>, <fstream>, <cstring>, so everything related to ofstream and strings should be included.
Hi again,

I sorted it out. I decided to just cout << name.length() to see if it returned anything sane and noticed I was getting values that were complete garbage. I thought maybe there might be a problem with Creature::getname() but it is used elsewhere in a "look" command and works perfectly fine.

What I think I was doing wrong:
I was not calling Map::savemap() before exiting the program. I had written:
1
2
3
4
Map::~Map()
{
this->savemap();
}

with the thought process that it would save the map on exit, but I'm guessing that this is a generically terrible idea because all sorts of other classes would also call their destructors and not be what I expect them to be anymore. Putting it back to how it was on my first try with file2 << name; and calling Map::savemap() before returning, instead of assuming it would work right to shove it into the destructor, fixed the problem.
Last edited on
Topic archived. No new replies allowed.