0

So I have a task to read two 2d arrays from a .txt file. The file looks like this:

2 3 4 5 6 7
2 6 8 2 4 4
6 3 3 44 5 1
#
4 2 1 6 8 8
5 3 3 7 9 6
0 7 5 5 4 1

The '#' character is used for defining a boundary between two arrays.

And both of 2d arrays has to be dynamically allocated. This is what I have:

int col = 0, row = 1;
int temp = 0;
char c;
ifstream file("input1.txt");
col = 0;
row = 1;
// calculating the no. of rows and columns of first 2d array in the text file (don't know how to do that for the second but this works perfectly)
do {
    file.get(c);
    if ((temp != 2) && (c == ' ' || c == '\n'))
        col++;
    if (c == '\n')
    {
        temp = 2;
        row++;
    }
} while (file);
// Used for rewinding file.
file.clear();
file.seekg(0, ios::beg);
// now I am using the info on rows and columns to dynamically allocate 2d array.(this is working fine too)
int** ptr = new int*[row];
for (int i = 0; i < col; i++)
{
    ptr[i] = new int[col];
}
// here I am filling up the first 2d array.
for (int i = 0; i < row; i++)
{
    for (int k = 0; k < col; k++)
    {
        file >> ptr[i][k];
        cout << ptr[i][k] << ' ';
    }
    cout << endl;
}
// code above works fine when there is only one matrix in file(without the '#' sign)
// these are used for storing dimensions of second 2d array and for dynamically allocating him
int row_two = 1, col_two = 0;

Now, what should I do next in order to recognize the '#' character and continue reading the next matrix? Next 2d array should be called ptr_two.

Just to note, I can't use vectors, only 2d arrays.

Eso Teric
  • 49
  • 1
  • 9
  • What is `fajl`? Also, you should find a way to do it without reading the file twice. Consider using 'getline()' and `stringstream`. – Dwayne Towell Dec 29 '14 at 01:15
  • You can use a dynamic storage container and just add a char each time you read one. No need to reread the file – dwn Dec 29 '14 at 01:19
  • please revise your question. – Irrational Person Dec 29 '14 at 01:23
  • @DwayneTowell 'fajl' is the name for file in my language. fixed it now. I thought of that, it would be great if I could find a way to read whole file only once but I don't know how to do that. And I really don't know how to use `stringstream` I am still at the beginning of c++.. – Eso Teric Dec 29 '14 at 01:23
  • @dwn how do I do that? What is storage container? – Eso Teric Dec 29 '14 at 01:25
  • ON STRINGSTREAM: http://www.eecis.udel.edu/~breech/progteam/stringstream.html ON VECTOR: http://www.cprogramming.com/tutorial/stl/vector.html – dwn Dec 29 '14 at 01:31
  • And how to use them both to solve this task: [see it live](http://ideone.com/QfG0aN). I have doubts its what your instructor wants, but anyone solving this as a real-world task would likely do something similar. Best of luck. – WhozCraig Dec 29 '14 at 01:36
  • @WhozCraig well, i need those two 2d arrays to perform some operations on them. Thanks for the solution but I can't use vectors since we haven't done them yet(should have put that in description) Is there a way to do it without them? Also what does the line `*pm = &m1;` at the beginning of the main do? – Eso Teric Dec 29 '14 at 01:41
  • `pm` points to "the matrix" being read. Note how it switches to `m2`'s address after the `'#'` encounter. And i suspected you couldn't use vectors (or most of the rest of this), but that's how it *would* be done (or similar) in real-world-practice. Thus why I mentioned it. – WhozCraig Dec 29 '14 at 01:43

1 Answers1

0

This is going a bit further than you wanted, but the basic concept is there. In short, use the file.tellg() function to save your current position. You can use it later to return to your spot.

My modifications basically allow you to pull in any number of tables. It does not, however, handle jagged tables. It also does not properly handle the edge case where your file ends with the '#' character (empty table). There is a situation at the end where, if you don't add a newline to the end of input1.txt, the last row is not going to be pulled.

Anyway, this code was modified without using a debugger to double check so I make no guarantees that it will start without some work. Or that you won't get an infinite loop when it does work.

// note that row starts from 0 because there is going to be an endline before the '#' character when it wasn't there before.
int col = 0, row = 0;
int temp = 0;
// new variables.
int table = 1, filepos = 0, curtable = 0;
char c;
ifstream file("input1.txt");
col = 0;
row = 1;

// calculating the number of tables.
do {
    file.get(c);
    if (c == '#')
        table++;
} while (file);

// Used for rewinding file.
file.clear();
file.seekg(0, ios::beg);

int*** ptrtable = new int**[table];

// calculating the no. of rows and columns of first 2d array in the text file (don't know how to do that for the second but this works perfectly)
do {
    file.get(c);
    if (c == ' ' || c == '\n')
        col++;
    if (c == '\n')
    {
        temp = 2;
        row++;
    }
    if (c == '#')
    {
        // Used for rewinding file.
        file.clear();
        temp = file.tellg;
        file.seekg(filepos, ios::beg);
        filepos = temp;

         // now I am using the info on rows and columns to dynamically allocate 2d array.(this is           working fine too)
         int** ptr = new int*[row];
         for (int i = 0; i < col; i++)
         {
             ptr[i] = new int[col];
         }
         // here I am filling up the first 2d array.
         for (int i = 0; i < row; i++)
         {
             for (int k = 0; k < col; k++)
             {
                 file >> ptr[i][k];
                 cout << ptr[i][k] << ' ';
             }
             cout << endl;
         }

         ptrtable[curtable] = ptr;

         // prepare for the next table.
         curtable++;
         temp = 0;
         row = -1;
         col = 0;

         file.clear();
         // filepos + 1 to jump past the '#' character.
         file.seekg(filepos + 1, ios::beg);

    }

} while (file);
MingShun
  • 287
  • 3
  • 11