| | |
filestream && multidimensional arrays
Please support our C++ advertiser: Intel Parallel Studio Home
![]() |
•
•
Join Date: Oct 2005
Posts: 4
Reputation:
Solved Threads: 0
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
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
•
•
Join Date: Jul 2005
Posts: 1,671
Reputation:
Solved Threads: 261
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.
•
•
Join Date: Oct 2005
Posts: 4
Reputation:
Solved Threads: 0
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 

C++ Syntax (Toggle Plain Text)
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 }
•
•
Join Date: Jul 2005
Posts: 1,671
Reputation:
Solved Threads: 261
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.
For some other comments, see below.
C++ Syntax (Toggle Plain Text)
//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. */
•
•
Join Date: Oct 2005
Posts: 4
Reputation:
Solved Threads: 0
ohhh well i guess i shoulda included the whole program
C++ Syntax (Toggle Plain Text)
#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; }
•
•
Join Date: Jul 2005
Posts: 1,671
Reputation:
Solved Threads: 261
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.
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.
•
•
Join Date: Oct 2005
Posts: 4
Reputation:
Solved Threads: 0
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.
C++ Syntax (Toggle Plain Text)
#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; }
•
•
Join Date: Jul 2005
Posts: 1,671
Reputation:
Solved Threads: 261
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.
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.
•
•
Join Date: Oct 2009
Posts: 2
Reputation:
Solved Threads: 0
0
#9 25 Days Ago
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.
•
•
Join Date: Oct 2009
Posts: 2
Reputation:
Solved Threads: 0
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.
![]() |
Similar Threads
Other Threads in the C++ Forum
- Previous Thread: Returning a pointer for a 2d array
- Next Thread: Viewing .exe File Source / Editing .exe File
| Thread Tools | Search this Thread |
api array beginner bitmap c++ c/c++ calculator char char* class classes code coding compile compiler console conversion count database delete desktop developer directshow dll download dynamic email encryption error file forms fstream function functions game givemetehcodez google graph gui homeworkhelper iamthwee ifstream input int integer java lib linkedlist linker linux loop looping loops map math matrix memory multiple news node number numbertoword output parameter pointer problem program programming project python random read recursion recursive reference return rpg sorting string strings struct temperature template templates test text text-file tree unix url variable vector video visualstudio win32 windows winsock word wordfrequency wxwidgets






