954,483 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

Help with writing file characters to a 3D array

I am trying to read and write a text file into an array and then store it back into the text file. The main problem i am having is the storing the file character by character into the 3D array.

Here is my code:

#include <iostream>
#include <fstream>
using std::ofstream;
using namespace std;

int main()
{
    char cabin[2][3][12];
    char ch, res;
    int num, lvl=0, row=0, col=0;

    
    ifstream indata;
    indata.open("littleswandb.txt");
    
    if(!indata) 
    { 
      cout << "File could not be opened" << endl;
      system("pause");
      return 0;
    }

      indata >> ch;
       while (!indata.eof()) 
       { // keep reading until end-of-file
       num=0;
         while(num<4)
         {
          cout << ch;
          indata >> ch;
          num =num +1;
          } // sets EOF flag if no value found
          cout << endl;
       }
       indata.close();
    system("pause");

    cout << "Would you like to make a reservation? Y/N" << endl;
    cin >> res;
    while ((res == 'Y') || (res == 'y'))
       {  
                
             cout << "Which Level Would you like to reserve? 1-3" << endl;
             cin >> lvl;
             cout << "Which Row Would you like to reserve? 1-13" << endl;
             cin >> row;
             cout << "Which Colunm Would you like to reserve? 1-4" << endl;
             cin >> col;
             lvl = lvl - 1; //Minus 1 for array
             row = row - 1; //Minus 1 for array
             col = col - 1; //Minus 1 for array
             
             if (cabin[lvl][row][col] != 'X')
             {
                cabin[lvl][row][col] = 'X';
                lvl = lvl + 1; //Plus 1 after array use
                row = row + 1; //Plus 1 after array use
                col = col + 1; //Plus 1 after array use
                cout << "You have booked the Cabin on Level: " << lvl 
                     << " Row: " << row 
                     << " Colunm: " << col << endl;
                
                //output the array onto the screen     
                for(int a=0; a<3; a++)//Levels
                {
                    for(int b=0; b<13; b++)//Rows
                    {
                       for(int c=0; c<4; c++)//Colunms
                       {
                          cout << cabin[a][b][c];
                       }
                       cout << endl;
                    }
                cout << endl;
                }                
                               
             ofstream outdata("littleswandb.txt");
             for(int d=0; d<3; d++) // Levels
             {
                 for(int e=0; e<12; e++) //Rows
                 {
                     for(int f=0; f<4; f++) // Colunms
                             outdata<<cabin[d][e][f]; // store array into file
                     outdata<< endl;
                 }
                 outdata<< endl;
             }
             outdata.close(); 
                system("pause");
             }
             else
                 cout << "That cabin is already booked" << endl;
                 cout << "Would you like to try another cabin? Y/N" << endl;
                 cin >> res;
       }
    cout << "Thank you. Good bye." << endl;
       system("pause");
    return 0;
}
bill_
Newbie Poster
23 posts since Mar 2010
Reputation Points: 10
Solved Threads: 0
 

Can you show an example data file? I think if you know all the dimensions ahead of time you could just use a for loop to read in the data and make things slightly easier on yourself.

jonsca
Quantitative Phrenologist
Team Colleague
5,621 posts since Sep 2009
Reputation Points: 1,165
Solved Threads: 581
 

the text file is representing a cruise chip database where 'B' is a balcony cabin, 'W' is a window cabin, and 'I' is an inside cabin. there are 3 levels in the cruise ship, with 4 colunms and 13 rows. that is where the 3d array comes in "cabin[2][3][12]".
the following is what is inside a text file named "littleswandb.txt"

BIIB
BIIB
BIIB
BIIB
BIIB
WIIW
WIIW
WIIW
WIIW
WIIW
WIIW
WIIW
WIIW
BIIB
BIIB
BIIB
BIIB
BIIB
WIIW
WIIW
WIIW
WIIW
WIIW
WIIW
WIIW
WIIW
BIIB
BIIB
BIIB
BIIB
BIIB
WIIW
WIIW
WIIW
WIIW
WIIW
WIIW
WIIW
WIIW

bill_
Newbie Poster
23 posts since Mar 2010
Reputation Points: 10
Solved Threads: 0
 

A quick point before anything else
there are 3 levels in the cruise ship, with 4 colunms and 13 rows. that is where the 3d array comes in "cabin[2][3][12]".
is incorrect. If you had a cruiseship of those dimensions theindexes of your array would go from cabin[0][0][0] to cabin[2][3][12] but your array must be declared

char cabin[3][4][13];
jonsca
Quantitative Phrenologist
Team Colleague
5,621 posts since Sep 2009
Reputation Points: 1,165
Solved Threads: 581
 

Actually that may be a big part of your problem. Are you overrunning the array when you try to write it out? I'm not convinced you're reading it in as you want to either...

jonsca
Quantitative Phrenologist
Team Colleague
5,621 posts since Sep 2009
Reputation Points: 1,165
Solved Threads: 581
 

i changed the array and the output is still the same. (random symbols). Also i thought that array[3] had 4 memory slots. so that is why i had the array number set to 1 less then wat i needed

bill_
Newbie Poster
23 posts since Mar 2010
Reputation Points: 10
Solved Threads: 0
 
i changed the array and the output is still the same. (random symbols). Also i thought that array[3] had 4 memory slots. so that is why i had the array number set to 1 less then wat i needed


Why wouldarray[3] have 4 slots? It only has 3, as the number signifies -- array[0] to array[2]

WaltP
Posting Sage w/ dash of thyme
Moderator
10,505 posts since May 2006
Reputation Points: 3,348
Solved Threads: 944
 

well i have changed them to cabin[3][4][13] now. should i change the for loop and get rid of the minus 1 to lvl, row, col and plus 1 parts lvl, row, col?

bill_
Newbie Poster
23 posts since Mar 2010
Reputation Points: 10
Solved Threads: 0
 
well i have changed them to cabin[3][4][13] now. should i change the for loop and get rid of the minus 1 to lvl, row, col and plus 1 parts lvl, row, col?

No, don't change the -1 for any of the dimensions, as you still need that since you are going from [0][0][0] to [2][3][12] over the range of the indexes.

jonsca
Quantitative Phrenologist
Team Colleague
5,621 posts since Sep 2009
Reputation Points: 1,165
Solved Threads: 581
 

so i should have:

char cabin[3][4][13];

Which gives me 156 slots
and
for the For loop

for(int a=0; a<3; a++)//Levels
      {
       for(int b=0; b<13; b++)//Rows
       {
        for(int c=0; c<4; c++)//Colunms
        {
            cout << cabin[a][c][b];
        }
        cout << endl;
       }
      cout << endl;
      }
bill_
Newbie Poster
23 posts since Mar 2010
Reputation Points: 10
Solved Threads: 0
 

Yes, except that's going to fill in a different order than 0,0,0 -> 0,0,1-> 0,0,2->... since the middle index will progress first. If you're going to have to read the file ( you wrote out) back into the program at a later time you'll want to keep a consistent format. That way your reading and writing loops will be similar to each other.

jonsca
Quantitative Phrenologist
Team Colleague
5,621 posts since Sep 2009
Reputation Points: 1,165
Solved Threads: 581
 

That looks good....

WaltP
Posting Sage w/ dash of thyme
Moderator
10,505 posts since May 2006
Reputation Points: 3,348
Solved Threads: 944
 

yep thats the order i want to read/write. e.g 0,0,1 | 0,0,2.
if i swap 'b' and 'c' i am still getting the random symbols.

cout << cabin[a][c][b];

also if i swap

if (cabin[lvl][row][col] != 'X')
{
      cabin[lvl][row][col] = 'X';

TO:

if (cabin[lvl][col][row] != 'X')
      {
      cabin[lvl][col][row] = 'X';

i still get errors

bill_
Newbie Poster
23 posts since Mar 2010
Reputation Points: 10
Solved Threads: 0
 

Can you put up your current code. Also, specify where you are getting the random symbols.

jonsca
Quantitative Phrenologist
Team Colleague
5,621 posts since Sep 2009
Reputation Points: 1,165
Solved Threads: 581
 

Here is the current code

#include <iostream>
#include <fstream>
      
using std::ofstream;
using namespace std;

int main()
{
      char cabin[3][4][13];
      char ch, res;
      int num, lvl=0, row=0, col=0;

      ifstream indata;
      indata.open("littleswandb.txt");
      if(!indata)
      {
                 cout << "File could not be opened" << endl;
                 system("pause");
                 return 0;
      }
      indata >> ch;
      while (!indata.eof())// keep reading until end-of-file
      { 
      num=0;
      while(num<4)
      {
          cout << ch;
          indata >> ch;
          num =num +1;
      } // sets EOF flag if no value found
      cout << endl;
      }
      indata.close();
      system("pause");
      
      cout << "Would you like to make a reservation? Y/N" << endl;
      cin >> res;
      while ((res == 'Y') || (res == 'y'))
      {
       cout << "Which Level Would you like to reserve? 1-3" << endl;
       cin >> lvl;
       cout << "Which Row Would you like to reserve? 1-13" << endl;
       cin >> row;
       cout << "Which Colunm Would you like to reserve? 1-4" << endl;
       cin >> col;

      //lvl = lvl -1; //Minus 1 for array
      //row = row -1; //Minus 1 for array
      //col = col -1; //Minus 1 for array

      if (cabin[lvl][row][col] != 'X')
      {
      cabin[lvl][row][col] = 'X';
      //lvl = lvl + 1; //Plus 1 after array use
      //row = row + 1; //Plus 1 after array use
      //col = col + 1; //Plus 1 after array use
      cout << "You have booked the Cabin on Level: " << lvl
           << " Row: " << row
           << " Colunm: " << col << endl;
      //output the array onto the screen
      for(int a=0; a<3; a++)//Levels
      {
       for(int b=0; b<13; b++)//Rows
       {
        for(int c=0; c<4; c++)//Colunms
        {
            cout << cabin[a][c][b];
        }
        cout << endl;
       }
      cout << endl;
      }
      /*ofstream outdata("littleswandb.txt");
      for(int d=0; d<3; d++) // Levels
      {
         for(int e=0; e<13; e++) //Rows
            {
                 for(int f=0; f<4; f++) // Colunms
                 { 
                    outdata<<cabin[d][e][f]; // store array into file
                 }
                 outdata<< endl;
            }
            outdata << endl;
      }
      outdata.close();
      system("pause");*/
      }
      else
      cout << "That cabin is already booked" << endl;
      cout << "Would you like to try another cabin? Y/N" << endl;
      cin >> res;
      }
cout << "Thank you. Good bye." << endl;
system("pause");
return 0;
}

im getting the random symbols as the output of the program in the command prompt. they seems to be in the format i want to display e.g 4 across, and then 13 down. then again for the 2nd and 3rd "level of the ship" / "dim of the array"

bill_
Newbie Poster
23 posts since Mar 2010
Reputation Points: 10
Solved Threads: 0
 

This is all happening from the output that's generated in lines 61-70? Ok, I was able to reproduce it. If that's not where it is we can look at some other areas.

I don't think it's related but you can eliminate the use of infile.eof() as your loop condition -- as using that can go one past the end of the list because of the way that method is designed.

jonsca
Quantitative Phrenologist
Team Colleague
5,621 posts since Sep 2009
Reputation Points: 1,165
Solved Threads: 581
 

Are you sure you're reading the file correctly? What are you doing with the data?

Where did you initialize the cabin matrix? When you define a variable, if you don't initialize it they contain garbage values.

WaltP
Posting Sage w/ dash of thyme
Moderator
10,505 posts since May 2006
Reputation Points: 3,348
Solved Threads: 944
 

Change line 9 to:
char cabin[3][4][13]= {' '}; ** I should have thought of this earlier but the array was not initialized so you were printing out junk characters that were there when the array was created.
It may not solve all the problems but this explains what you were seeing.

I think the input is probably ok as it echos properly on the screen.

** This seems to work but I do not know if that's the proper way to do it. It won't allow any other characters in it's place.

jonsca
Quantitative Phrenologist
Team Colleague
5,621 posts since Sep 2009
Reputation Points: 1,165
Solved Threads: 581
 

Jonsca:
by "infile.eof()" do you mean "indata.eof()"? and if i take it out that will mean that it will not know when to stop reading the file.

WaltP:
when it reads a character i get it to display the character so that i can see that it is reading it right. am i doing it wrong?

what i want to do with the data later on is change one char, in a certatin spot in the file to an 'X' to represent a reserved spot in my database.

i had the cabin matrix initialized on line 9. is this wrong?

jonsca:
i changed line 9 to what u said but now i am getting a bunch of blank spaces and an 'X'. and then more spaces then another 'X', then spaces and random symbols again.

bill_
Newbie Poster
23 posts since Mar 2010
Reputation Points: 10
Solved Threads: 0
 
Jonsca: by "infile.eof()" do you mean "indata.eof()"? and if i take it out that will mean that it will not know when to stop reading the file.


Yes I meant indata. I'm talking about a situation where you use your indata>>ch as the loop variable for the while loop so that when you run out of characters it returns null and the loop ends. The .eof method is prone to scanning in the last character multiple times. Read this post by Dave Sinkula it gives all the details. For right now, though I don't think it's the primary problem but I was examining it as a possibility before.
WaltP:
when it reads a character i get it to display the character so that i can see that it is reading it right. am i doing it wrong?
Unless you're doing something fluky both times and everything's coming out right side up by chance I think that part is ok. Don't quote me on that.what i want to do with the data later on is change one char, in a certatin spot in the file to an 'X' to represent a reserved spot in my database.

jonsca:
i changed line 9 to what u said but now i am getting a bunch of blank spaces and an 'X'. and then more spaces then another 'X', then spaces and random symbols again.
And it seems to be doing that okay on my end it's just there's no other characters around it to reference where the X is. I was not getting the random symbols anymore.i had the cabin matrix initialized on line 9. is this wrong?
You had declared it but not initialized it, in other words it had no values just whatever happened to be in memory at that location.
My approach had it take a blank space for each element of the array. However, I'm working from memory and I can find no written evidence to verify that technique works in all cases. You could initialize it with another character or a space by setting up 3 nested for loops. I'm 100 % confident that particular scenario will work. Give that a try and initialize it to stars or dashes or something so you can see the Xs falling in line over your diagram.

jonsca
Quantitative Phrenologist
Team Colleague
5,621 posts since Sep 2009
Reputation Points: 1,165
Solved Threads: 581
 

This question has already been solved

Post: Markdown Syntax: Formatting Help
You
 
View similar articles that have also been tagged: