Cheers guys, my first post here. I've been reading a lot but i can't seem to find any scenario that helps me out with my problem. I'm trying to take input from a file in the form of some shape... rectangle/square, and store it somehow. The shape is composed of letters and represents a map. Also I'm going to be using an (x,y) coordinate system later on so i have figured out that using a multidimensional array is imperative. I've seemed to have pseudo coded this well, but I can't seem to find to convert from paper to keyboard reading the file into a multidimensional array. So far i know i need the getline function... but i don't quite understand how i'm going to fill the multidimensional array with a getline function.

If someone could give me an example or nudge me in the right direction that would be awesome. Thanks!

btw the input file looks soemthing like... where x is a wall and o is walking area

xxxxxxxxxxxxxxxx
xoooxxxxxxxxoox
xoooxxxxoooooxx
xoooxxoooooxxxx
xoooxxxxooooooo
xxxxooooooxxxxx
xxxxxxoooooxxxx
xxxxxxxxxxxoxxxx

Recommended Answers

All 9 Replies

To store that type of information in an array I would use a 2D array of char. I would read in one char at a time, using a nested for loop where the outer loop controlled which row I was in and the inner loop controlled which column I was in. Then I could explicitly access any element within the array by using syntax such as myArrayofChar[row][col]. Remember that the indexes of an array are zero based, so the first row has index 0 and the 5 column has index 4, not five. If I knew ahead of time the number of rows and columns I'd declare the array using syntax, assuming it wasn't huge in size. Otherwise, I'd declare the array on the heap using dynamic memory with the keywords new[] and delete[] and loops as befitting the mulidimensional characterstics of the array.

Thanks Lerner for the reply! ... So i got that much now i have this really odd problem. I think when i count my columns and rows in the file it's not resetting when i actually want to read in the letters from the file. I've tried opening and closing and .clear()... none of these things help out :(

class cave
{
public:
    cave();
	void cavemap();
	void set_numrows();
	void make_move();

private:
	ifstream infile;
	char letterz;
	int numrows;	// This is the number of rows
	int numcols;	// This is the number of columns
	char **multArray;
};

void cave::cavemap()
{	
   infile.open("cavemap.txt");
   
   //Block of code to find number of columns
   ////////////////////////////
   string str;
   getline(infile, str);
   numcols=str.length();
   infile.close();
   ////////////////////////////

   infile.open("cavemap.txt");
   while(!infile.eof()) //while-loop to count rows
   {
	    string temp;
        getline(infile, temp);
		numrows++;
   }

   multArray = new char * [numrows];    // allocate the rows

   for (int row = 0; row < numrows; row++) //allocate columns
     	multArray[row] = new char [numcols]; 
    
    for (int r = 0; r < numrows; r++) //double for-loop to populate the 2D array
    {
		for (int c = 0; c < numcols; c++) 
		{
			infile>>letterz;
	    	multArray[r][c] = letterz;
	    	cout << setw(2) << multArray[r][c];
		}
		cout << endl;
    }
    for (int row2 = 0; row2 < numrows; row2++)
		delete[] multArray[row2]; // destroys memory of a single row

    delete[] multArray; // destroys the pointers to each row
}

In the code you've posted I don't see where you initialize numrows to a value before you call the postfix increment operator on it. That would be a no-no.

For some other comments, see below.

//Block of code to find number of columns
   ////////////////////////////
   string str;

   //numrows should have a value of zero here

   getline(infile, str);

   //you somehow need to give numrows the value of one here

   numcols=str.length();
   infile.close();
   ////////////////////////////

   //infile is already open here, don't reopen it.
   infile.open("cavemap.txt");

   //don't use eof() as the terminating condition for the while loop.  If you want to know the technical reason why, ask.  Otherwise just accept the advice.  Use while(getline(infile, str)) instead and don't call getline() within the loop body.
   while(!infile.eof()) //while-loop to count rows
   {
                 //you really don't need another variable, just keep using str
	    string temp;
        getline(infile, temp);
		numrows++;
   }

  /*This loop will stop when EOF is found or something else causes infile to go into a 
failed state.  To be sure all of file was read you can check .eof().  If it is true, then you know you successfully read the whole file. 

However, you want to reread the file now char by char.  To do that you need 
to get back to the beginning of the file.  To do that I would call the istream clear() method on infile (because finding EOF put infile into a failed state) and then I would either use the istream seekg() method with the appropriate parameters or close infile and reopen it (when you reopen it it should default to the beginning of the file you associate it with).  Now you can reread the file char by char to fill in multarray using the nested loop.  
*/

ohhh well i guess i shoulda included the whole program

#include <iostream> // for cout
#include <iomanip> // for setw
#include <fstream>
#include <string> 
#include <cstring>

using namespace std;

class cave
{
public:
	void cavemap();
	void set_numrows();
	void make_move();

private:
	ifstream infile;
	char letterz;
	int numrows;	// This is the number of rows
	int numcols;	// This is the number of columns
	char **multArray;
};

void cave::cavemap()
{	
   infile.open("cavemap.txt");
   
   //Block of code to find number of columns
   ////////////////////////////
   string str;               //
   getline(infile, str);     //
   numcols=str.length();     //  
   ////////////////////////////

   while(!infile.eof()) //while not end of file get each line and increase the number of rows by 1.
   {
	   string temp;
        getline(infile, temp);
		numrows++;
   }

   multArray = new char * [numrows];    // allocate the rows

   for (int row = 0; row < numrows; row++)   // now allocate the columns
     	multArray[row] = new char [numcols]; 
    
    for (int r = 0; r < numrows; r++) //double for-loop to populate the 2D array
    {
		for (int c = 0; c < numcols; c++) 
		{ // :)
			infile>>letterz;
	    	multArray[r][c] = letterz;
	    	cout << setw(2) << multArray[r][c];
		}
		cout << endl;
    }
	cin>>letterz;
    for (int row2 = 0; row < numrows; row++)
		delete[] multArray[row2]; // destroys memory of a single row

    delete[] multArray; // destroys the pointers to each row
}

void cave::set_numrows()
{
	numrows = 1;
}

void cave::make_move()
{
	

}


int main ()
{
	cave caveobj;

	caveobj.cavemap();

    return 0;
}

In main() you have the following two lines:

cave caveobj;
caveobj.cavemap();

The first line calls the default constructor for the cave class. Since you don't explicitly declare/define a default constructor the compiler does it for you. The default default constructor will not initialize any data members for you. So numrows is left uninitialized at this time.

The second line calls the cavemap() method on the object called caveobj which is an instance of the cave class. However, numrows isn't initialized in that method either because there is no explicit initialization/assignment of a value before the postscript operator is called and there is no call to set_numrows() from within cavemap() that would set numrows to 1. Either use an initializer list in your own default constructor to set the value of numrows to the desired default value, OR explicitly assign a default value to numrows within cavemap() before you call the postscript operator, OR call set_numrows() within cavemap() before you call the postscript operator on numrows.

I see... I've made some revisions since then.. but my map still doesn't display correctly :mad: I have a mutator function set_rows that sets numrows to one. Then i call my cave_map() member function to populate my 2d array. Next i have a function called make_move(), which checks all the places around the current position using (x, y) coordinates and after moving sets the last place to '*'. I do this because i have to have a way to backtrack, so eventually i'll need a way to store these places in an array so if i come to a dead end on the map i can backtrack to the last place. Only problem is I don't know how far i would backtrack. I'm thinking maybe start a count sequence after a path is chosen if there is two choics... if there's a dead end back track until the counter is 0.

#include <iostream> // for cout
#include <iomanip> // for setw
#include <fstream>
#include <string> 
#include <cstring>

using namespace std;

class cave
{
public:
    cave();
	void cavemap();
	void set_numrows();
	void make_move();
	void set_letterz();
	void map_output();

private:
	ifstream infile;
	char letterz;
	int numrows;	// This is the number of rows
	int numcols;	// This is the number of columns
	char **multArray;  // Note: We use int ** because we want multArray to be  a
                   // a pointer to pointer to a int (an array of arrays...)
    int x, y;
};

cave::cave()
{
    x = 0;
    y = 0;
}
void cave::set_letterz()
{
    letterz=' ';
}

void cave::cavemap()
{	
   infile.open("cavemap.txt");
   if(infile.fail())
   {
       cout<<"File opening fail"<<endl;
   }   
   //Block of code to find number of columns
   ///////////////////////////////////////////////////////////////
   string str;                                                                //
   getline(infile, str);                                                      //
   numcols=str.length();                                                 //
                                                                                 //
                                                                                 //
   while(getline(infile, str)) //while-loopo to count rows        //                                                         
   {                                                                            //
		numrows++;                                                //
   }                                                                          //
   infile.clear();                                                         //
  ////////////////////////////////////////////////////////////////
   

   multArray = new char * [numrows];    // allocate the rows


   for (int row = 0; row < numrows; row++)   // now allocate the columns
     	multArray[row] = new char [numcols]; 
    
    for (int r = 0; r < numrows; r++) //double for-loop to populate the 2D array
    {
		for (int c = 0; c < numcols; c++) 
		{
			infile>>letterz;
	    	multArray[r][c] = letterz;
	    	cout << setw(2) << multArray[r][c];
		}
		cout << endl;
		infile.close();
    }
    for (int row2 = 0; row2 < numrows; row2++)
		delete[] multArray[row2]; // destroys memory of a single row

    delete[] multArray; // destroys the pointers to each row
}

void cave::set_numrows()
{
	numrows = 1;
}

void cave::make_move() //sequence of if-else statements checks all 8 directions for "o" and then sets the previous 
                       //"y" = "o" and the next "o" equal to "y"
{
    if(multArray[x+1][y+1]='o') //Check Northeast
    {
        multArray[x][y]='*';
        multArray[x+1][y+1]='y';
    }
    else if(multArray[x+1][y]='o')//Check East
    {
        multArray[x][y]='*';
        multArray[x+1][y]='y';
    }
     else if(multArray[x+1][y-1]='o') //check Southeast
    {
        multArray[x][y]='*';
        multArray[x+1][y-1]='y';
    }
     else if(multArray[x][y-1]='o') //Check South
    {
        multArray[x][y]='*';
        multArray[x][y-1]='y';
    }
     else if(multArray[x-1][y-1]='o')//check Southwest
    {
        multArray[x][y]='*';
        multArray[x-1][y-1]='y';
    }
     else if(multArray[x-1][y]='o') //Checks west
    {
        multArray[x][y]='*';
        multArray[x+1][y]='y';
    }
     else if(multArray[x-1][y+1]='o') //Checks NorthWest
    {
        multArray[x][y]='*';
        multArray[x-1][y+1]='y';     
    }
      else if(multArray[x][y+1]='o') //Checks North
    {
        multArray[x][y]='*';
        multArray[x+1][y]='y';
    }
}
void cave::map_output()
{
    
    for (int r = 0; r < numrows; r++) //double for-loop to populate the 2D array
    {
		for (int c = 0; c < numcols; c++) 
		{
	    	cout << setw(2) << multArray[r][c];
		}
		cout << endl;
	
    }
}
    


int main ()
{
  
	cave caveobj;
	caveobj.set_numrows();
	caveobj.cave_map();
	caveobj.make_move();
	caveobj.map_output();

	

    return 0;
}

When you clear() the stream it doesn't reposition the pointer to the beginning of the file. You can do that by using seekg() with the appropriate parameters, or by closing and reopening the same file.

Then, don't destroy the memory of the cave before you actually search the maze! Destroy the memory after you've found a solution, prove there is no solution, and do something with that knowledge. As it is now, when you successfully load the maze from the file to your program you won't be able to do anything with make_move(), because the maze will be gone already before you call make_move().


Maze searching can be a maze itself. The idea of using an array of neighbors and somehow keeping track of which ones have already been visited sounds logical. Then one approach would be to consider having a dequeue of cells representing the successfully visited cells (the "path" or "solution"). Each successfully visited cell would be pushed on the back of the dequeue. If a dead end was found then pop the current cell from the end stack to go "back" to the next available cell. In this scenario, stop searching if "goal" is found or if the dequeue is empty. IF "goal" found, then print the dequeue from begining to end to print a given solution. IF the dequeue was empty, then the maze has no solution. The number of steps from start to goal would be the size of the dequeue if you wanted to search the maze again to see if there was another, or shorter, solution.

Write a function for seat allocate & seat reserved.Seat allocate array and seat reserver array.Seat allocate array is of 10*20 & each row & column represent A1,A2....;B1,B2.....;J1,J2 & so on i.e row are A to J whereas col starts from 0 to 19.Each cell in the table represent either 0 or 1. 0 rep seat available, 1 repr seat reserved. Seat allocation starts from highest to lowest.And row j is highest, i is second highest and so on.Max 20 seats can be booked at a time. if seat is available print the seat no like. like "B2" i.e (2 row, 3 col) otherwise Print "Seats are not available." and we must book consecutive seats only.

Write a function for seat allocate & seat reserved.Seat allocate array and seat reserver array.Seat allocate array is of 10*20 & each row & column represent A1,A2....;B1,B2.....;J1,J2 & so on i.e row are A to J whereas col starts from 0 to 19.Each cell in the table represent either 0 or 1. 0 rep seat available, 1 repr seat reserved. Seat allocation starts from highest to lowest.And row j is highest, i is second highest and so on.Max 20 seats can be booked at a time. if seat is available print the seat no like. like "B2" i.e (2 row, 3 col) otherwise Print "Seats are not available." and we must book consecutive seats only.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.