-
Hi, I am having trouble with (I think) file i/o. The relevant code is below
Code:
//main.cpp
int main (int argc, char * const argv[]) {
std::string filename;
cout<<"Please enter a filename of a map"<<endl;
cin>>filename;
Room theroom(filename);
cout<<theroom.getMap()->toString()<<endl;
}
Code:
#ifndef ROOM_H
#define ROOM_H
#include "Grid.h"
#include <string>
class Room {
public:
Room(std::string&);
~Room();
Grid*& getMap();
private:
Grid* map;
};
#endif
Code:
//room.cpp
Room::Room(std::string& filename) {
std::ifstream thefile(filename.c_str(), std::ios::in);
if(!thefile) {
std::cout<<"File could not be found"<<std::endl;
exit(1);
}
int rowcount = 0; //row dimension var
char colcount[256];
while(!thefile.getline(colcount, 256).eof()) {
rowcount++;
std::cout<<colcount<<std::endl;
}
//once more for last line
rowcount++;
std::cout<<colcount<<std::endl;
//make 2d char array
char** themap = new char*[rowcount];
for(int i=0;i<rowcount;i++)
themap[i] = new char[strlen(colcount)];
std::cout<<"rowcount: "<<rowcount<<" colcount: "<<strlen(colcount)<<"\n";
int cols = (int)strlen(colcount);
map = new Grid(themap, rowcount, cols);
thefile.close();
}
Room::~Room() {}
Grid*& Room::getMap() {return map;}
Code:
#ifndef GRID_H
#define GRID_H
#include<string>
class Grid {
public:
Grid();
Grid(char**&, int&, int&);
~Grid();
char**& getMap();
char getPos(int&, int&);
std::string toString();
private:
char** map;
int rows;
int cols;
};
#endif
Code:
//grid.cpp
Grid::Grid() {}
Grid::Grid(char**& themap, int& r, int& c) : map(themap), rows(r), cols(c) {
std::cout<<"grid constructor\n";
std::cout<<"r: "<<r<<" c: "<<c<<"\n";
std::cout<<"rows: "<<rows<<" cols: "<<cols<<"\n";
}
//todo
Grid::~Grid() {
}
char**& Grid::getMap() {return map;}
char Grid::getPos(int& row, int& col) {return map[row][col];}
std::string Grid::toString() {
std::ostringstream result;
result<<"rows: "<<rows<<" cols: "<<cols<<"\n";
for(int row=0;row<rows;row++) {
for(int col=0;col<cols;col++) {
result<<getPos(row, col);
std::cout<<"grid("<<row<<","<<col<<"): "<<map[row][col]<<std::endl;
if(col == cols-1)
result<<"\n";
} //end inner for
} //end outter for
return result.str();
}
I want to pass a string with a filename to Room. Then Room should create a 2D char array and pass that to a Grid constructor to make a Grid. Whenever I run this, the grid constructor cout lines print correct information. My file is just a square outlined with # symbols and a path going up through the middle.
Code:
########### ########
# # # #
# # # #
# # # #
# # # #
# # # #
# # # #
# # # #
# # # #
########### ########
However, whenever I print the grid toString in main, I get nothing. The cout line in the function prints the correct row and column numbers, but everything is blank. Even if I call the toString right after I initialize map at the bottom of the Room constructor. I don't see why its not giving the map variable the right value. Can anyone explain to me whats wrong here? Any help is appreciated.
The # symbols are formatted wrong in the post. In my file, they form a square.
The actual output is -
########### ########
# # # #
# # # #
# # # #
# # # #
# # # #
# # # #
# # # #
# # # #
########### ########
rowcount: 10 colcount: 20
grid constructor
r: 10 c: 20
rows: 10 cols: 20
grid(0,0):
grid(0,1):
grid(0,2):
grid(0,3):
grid(0,4):
grid(0,5):
grid(0,6):
grid(0,7):
grid(0,8):
grid(0,9):
grid(0,10):
grid(0,11):
grid(0,12):
grid(0,13):
grid(0,14):
grid(0,15):
grid(0,16):
grid(0,17):
grid(0,18):
grid(0,19):
grid(1,0):
grid(1,1):
grid(1,2):
grid(1,3):
grid(1,4):
grid(1,5):
grid(1,6):
grid(1,7):
grid(1,8):
grid(1,9):
grid(1,10):
grid(1,11):
grid(1,12):
grid(1,13):
grid(1,14):
grid(1,15):
grid(1,16):
grid(1,17):
grid(1,18): \377
grid(1,19): \377
grid(2,0):
grid(2,1):
grid(2,2):
grid(2,3):
grid(2,4):
grid(2,5):
grid(2,6):
grid(2,7):
grid(2,8):
grid(2,9):
grid(2,10):
grid(2,11):
grid(2,12):
grid(2,13):
grid(2,14):
grid(2,15):
grid(2,16):
grid(2,17):
grid(2,18):
grid(2,19):
grid(3,0):
grid(3,1):
grid(3,2):
grid(3,3):
grid(3,4):
grid(3,5):
grid(3,6):
grid(3,7):
grid(3,8):
grid(3,9):
grid(3,10):
grid(3,11):
grid(3,12):
grid(3,13):
grid(3,14):
grid(3,15):
grid(3,16):
grid(3,17):
grid(3,18):
grid(3,19):
grid(4,0):
grid(4,1):
grid(4,2):
grid(4,3):
grid(4,4):
grid(4,5):
grid(4,6):
grid(4,7):
grid(4,8):
grid(4,9):
grid(4,10):
grid(4,11):
grid(4,12):
grid(4,13):
grid(4,14):
grid(4,15):
grid(4,16):
grid(4,17):
grid(4,18):
grid(4,19):
grid(5,0):
grid(5,1):
grid(5,2):
grid(5,3):
grid(5,4):
grid(5,5):
grid(5,6):
grid(5,7):
grid(5,8):
grid(5,9):
grid(5,10):
grid(5,11):
grid(5,12):
grid(5,13):
grid(5,14):
grid(5,15):
grid(5,16):
grid(5,17):
grid(5,18):
grid(5,19):
grid(6,0):
grid(6,1):
grid(6,2):
grid(6,3):
grid(6,4):
grid(6,5):
grid(6,6):
grid(6,7):
grid(6,8):
grid(6,9):
grid(6,10):
grid(6,11):
grid(6,12):
grid(6,13):
grid(6,14):
grid(6,15):
grid(6,16):
grid(6,17):
grid(6,18):
grid(6,19):
grid(7,0):
grid(7,1):
grid(7,2):
grid(7,3):
grid(7,4):
grid(7,5):
grid(7,6):
grid(7,7):
grid(7,8):
grid(7,9):
grid(7,10):
grid(7,11):
grid(7,12):
grid(7,13):
grid(7,14):
grid(7,15):
grid(7,16):
grid(7,17):
grid(7,18):
grid(7,19):
grid(8,0):
grid(8,1):
grid(8,2):
grid(8,3):
grid(8,4):
grid(8,5):
grid(8,6):
grid(8,7):
grid(8,8):
grid(8,9):
grid(8,10):
grid(8,11):
grid(8,12):
grid(8,13):
grid(8,14):
grid(8,15):
grid(8,16):
grid(8,17):
grid(8,18):
grid(8,19):
grid(9,0):
grid(9,1):
grid(9,2):
grid(9,3):
grid(9,4):
grid(9,5):
grid(9,6):
grid(9,7):
grid(9,8):
grid(9,9):
grid(9,10):
grid(9,11):
grid(9,12):
grid(9,13):
grid(9,14):
grid(9,15):
grid(9,16):
grid(9,17):
grid(9,18):
grid(9,19):
rows: 10 cols: 20
Except the #s are formatted right. I don't know what the \377 means.
-
\377 is the octal (base 8) representation of a single character (usually a non-printable character).
In hex, this is 0xFF and decimal 255.
What it usually means is that you've read past the end of the file, and you have the casted value of EOF (typically -1) stored.
In short, look at your eof() handling. It seems overly complicated and messy to me.
Code:
while ( thefile.getline(colcount, 256) ) {
}
loops until the end of the file.
-
Well whenever I use that for my while condition, it only reads 11 for my rows and 0 for my columns.
-
OK - start with the basics, just write some code to read each line of the file.
Also, if the forum isn't rendering your room input file properly, then attach it to your post so we can see exactly what it looks like.
-
1 Attachment(s)
map
Okay, I'll go back to the basics and try to solve the problem. In the meantime, here is the file.
-
I updated your post to show the correct map file. Just so you know, it might look poor when you paste to the edit window, but the code tags will make it right again.
-
Okay, I got it working. In case anyone has the same problem, the code (with some debug lines I haven't taken out yet) is -
Code:
Room::Room(std::string& filename) {
std::stringstream tempmap; //temporary hold map
int colcount = 0; //col dimsension var
int rowcount = 0; //row dimension var
char receive[256]; //get lines from file
std::ifstream thefile(filename.c_str(), std::ios::in); //file input stream
//make sure the file exists
if(!thefile) {
std::cout<<"File could not be found"<<std::endl;
exit(1);
}
//go through file and get map
while(thefile.getline(receive, 256)) {
rowcount++; //add a row
std::cout<<receive<<std::endl;
tempmap<<receive<<std::endl; //pass line into tempmap
//set column dimension
colcount = strlen(receive);
} //end while
/*
std::cout<<tempmap.str()<<std::endl;
std::cout<<"colcount: "<<colcount<<std::endl;
std::cout<<"rowcount: "<<rowcount<<std::endl;
tempmap.getline(receive, 256);
std::cout<<receive<<std::endl;
*/
std::cout<<"\n\n";
//make 2d char array
char** themap = new char*[rowcount];
for(int i=0;i<rowcount;i++)
themap[i] = new char[colcount];
//initialize char array
for(int r=0;r<rowcount;r++)
for(int c=0;c<colcount;c++) {
//if newline char, conusme that
if((char)tempmap.peek() == '\n')
tempmap.get();
themap[r][c] = (char)tempmap.get();
}
std::cout<<"\n\n";
for(int r=0;r<rowcount;r++)
for(int c=0;c<colcount;c++) {
std::cout<<themap[r][c];
if(c == colcount-1)
std::cout<<"\n";
}
map = new Grid(themap, rowcount, colcount);
thefile.close();
}