Hello, I am happy to find this forum. I was trying to read a file to matrix matice.

The input file looks like this:
7 1 4 5 6 9
3 2 2 0 7 6
8 6 1 2 4 2
9 1 7 2 3 8

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main(int argc, char *argv[]) {
  
  string radka;
  
  char * pch;
  char * matice;
  char * chradka;
    
  int i=0;//cislo sloupce
  int j=0;//cislo radky
  int konecsouboru=0;
  
  
  ifstream soubor("F:\\v\\prog\\vstup2.txt");
  
  if (soubor.is_open())
  {
    konecsouboru=soubor.end;
    cout<<konecsouboru<<endl;
    
    matice = new char[konecsouboru+1,6];
    while(!soubor.eof() )
    {
      
      getline(soubor,radka);
      if(soubor.eof()) break;
      
      chradka=new char[radka.size()+1];
      strcpy(chradka,radka.c_str());

      cout << radka << endl;//comment 1
      i=0;
            
      pch = strtok(chradka," ");
      while (pch != NULL)
      {
            matice[i,j]=*pch;
            cout<<matice[i,j];//comment 2
            pch = strtok(NULL, " ");
           
            i++;
      }
      
      
      cout<<endl;
      cout<<matice[0,j]<<matice[1,j]<<matice[2,j]<<matice[3,j]<<matice[4,j]<<matice[5,j];//comment   3
      cout<<endl;            
      j++;
            
      delete[] chradka;
    }
   
    cout<<konecsouboru<<endl;
    for(j=0; j<konecsouboru+1;j++)
    {
             
             for(i=0; i<6;i++)
             {
                      cout<<"matice["<<i<<","<<j<<"]="<<matice[i,j];   
             }
             
             if(j<konecsouboru)cout<<endl;
             
    }
    
    delete[] matice;
    
    soubor.close();
  }

  else cout << "Soubor neslo otevrit."; 
  
  return 0;
}

With the input file at the beginning, the output looks like this:
2//should be a number of rows of the file minus 1
7 1 4 5 6 9//row read from file - comment 1
714569//row of the matrix parsed by strtok - comment 2
999999//the same matrix row after finishing loading the row by the //results of strtok function - comment 3
3 2 2 0 7 6
322076
666666
8 6 1 2 4 2
861242
222222
9 1 7 2 3 8
917238
888888
2//number of rows of the file again
//writing the matrix to screen to check how does it look like
matice[0,0]=9matice[1,0]=9matice[2,0]=9matice[3,0]=9matice[4,0]=9matice[5,0]=9
matice[0,1]=6matice[1,1]=6matice[2,1]=6matice[3,1]=6matice[4,1]=6matice[5,1]=6
matice[0,2]=2matice[1,2]=2matice[2,2]=2matice[3,2]=2matice[4,2]=2matice[5,2]=2

I can't find out why
1) I get 2 as a number of rows -1, when the input file has four rows
2) The matrix is not loaded by the values from file correctly

Could anybody please help me? I am trying to solve this problem for 3 days now:)

It should be a part of a much more complex algorithm and I am sad that I got stuck at this point.
Thank you very much for help.

mvmalderen commented: For using code tags on first post :) +5

Recommended Answers

All 10 Replies

First some remarks on your code:

while(!soubor.eof())
{
  getline(soubor,radka);
  if(soubor.eof()) break;
.
.
.

can be replaced by:

while(getline(soubor,radka))
{
.
.
.

and while (pch != NULL) is actually the same as while (pch) :P

Is the matrix always of the same dimension?

Member Avatar for iamthwee

At the moment the way you're doing it, looks more like c than c++.

I would be tempted to read the file in line by line (getline), delimit it using space (istream), parse it to check whether the values are actually integer, convert the string to an integer (stringstreams) than put them into an array or a vector if you want to be clever.

There are of course other ways.

commented: I agree +5

No, the matrix has 6 columns and unknown number of rows.

No, the matrix has 6 columns and unknown number of rows.

Then you should consider using a vector :)

Maybe you should try a simpler algorithm, like this one:

int i = 0, j = 0;               // Counters
string Buffer;                 // Acts as a buffer containing characters

while(getline(FileIn, Buffer, ' '))
{
       cout << "M[" << i << "][" << j << "] = " << Buffer << ' ';
       j++;
         
       if((j % 5) == 0)          // This is because there can only be 6 columns
       {
            i++;
            j = 0;
            cout << '\n';
       }
}

Of course, this would treat every matrix value as a string, but you get the general idea, don't you?

*Note*: This code is only a roughly-coded snippet. It will not show the output in the expected manner. It is only meant to give you an idea as to what you could do to solve your problem.

If you want to read in a matrix you need some considerations.

First of all you need some cind of datastructure to have the data in some datatype.

A int** would be very suitable.

But you need to know the dimesions,
you will get the number of columns after the first line,
but you need to loop through the entire row to get the number of lines.

So either make some "dynamic" datastructure, or just read the file 2 times.

It doesn't look like you are allocating any memory in your code snippet.

If you want to read in a matrix you need some considerations.

First of all you need some cind of datastructure to have the data in some datatype.

A int** would be very suitable.

But you need to know the dimesions,
you will get the number of columns after the first line,
but you need to loop through the entire row to get the number of lines.

So either make some "dynamic" datastructure, or just read the file 2 times.

It doesn't look like you are allocating any memory in your code snippet.

Well, of course I'm not allocating any memory for a matrix-like structure (2D Array) in my code snippet: Like I said, this is an example of a simple algorithm to print the contents of the matrix in the file. n:icon_rolleyes:

It can be very easily modified so that a 2 dimensional array of integers can hold the values. To do this, here is the same code snippet, modified.

int i = 0, j = 0;               // Counters
int (*Matrix)[5];               // Contains the Matrix
int RowSz = 0;                  // Holds the number of rows
string Buffer;                  // Acts as a buffer containing characters
    
while(getline(FileIn, Buffer, '\n'))  // Gets the number of lines in the file
     RowSz++;

cout << "\n\n\tNumber of Rows = " << RowSz << "\n\n\t";
         
Matrix = new int[RowSz][5];     // Allocate Memory to hold the matrix
    
FileIn.clear();                            // Flushes the stream
FileIn.seekg(ios::beg);             // Resets the File pointer to the beginning of the file
    
while(getline(FileIn, Buffer, ' '))
{
     Matrix[i][j] = stringToInt(Buffer);
      j++;
         
      if((j % 5) == 0)                  // This is because there can only be 6 columns
       {
            i++;
            j = 0;
       }
}

/* ... TODO: A function to display the matrix
             Cleanup code(free the allocated memory, close the file stream)
 */

and this would be the function to convert a string to an int:

int stringToInt(string In)
{
    int retInt;
    
    /* ... Okay, I took down this code ...
        ...  Its not very hard, just search the web if you have any difficulties, in fact this forum has the same topic covered numerous times ... */
    
    return retInt;                // Otherwise, return the string as an integer
}

I think this is very easily the simplest method to do this...

since the file being read is a matrix of "i x j". I would read the file first to get the dimension(read the file character by character to get the i), and read the total /n and /0 character to get the j. Then use these values for your 2 dimensional array with [j].

since the file being read is a matrix of "i x j". I would read the file first to get the dimension(read the file character by character to get the i), and read the total /n and /0 character to get the j. Then use these values for your 2 dimensional array with [j].

>read the file character by character to get the i

Really? Try it and see if it will work... Imagine that there are 64 characters in the file: in C++ a character is a single byte of memory, and can be anything from an alphabet to an escape sequence. So basically, even if its a two digit number you want to insert into the matrix, all you really have are two different digits. So then i would take the value 64. This would then mean that your matrix has 64 rows...

>read the total /n and /0 character to get the j

Again, try coding this into your algorithm... If every row is delimited by a NULL terminator ( \0 ) or by a new line character ( \n ), and there are 4 rows as such, then it would mean j will take the value 4.

This would then result in a matrix whose dimensions are [64][4]... :P

Do we really need such a measure for a not-so-difficult exercise?

>read the file character by character to get the i

Really? Try it and see if it will work... Imagine that there are 64 characters in the file: in C++ a character is a single byte of memory, and can be anything from an alphabet to an escape sequence. So basically, even if its a two digit number you want to insert into the matrix, all you really have are two different digits. So then i would take the value 64. This would then mean that your matrix has 64 rows...

>read the total /n and /0 character to get the j

Again, try coding this into your algorithm... If every row is delimited by a NULL terminator ( \0 ) or by a new line character ( \n ), and there are 4 rows as such, then it would mean j will take the value 4.

This would then result in a matrix whose dimensions are [64][4]... :P

Do we really need such a measure for a not-so-difficult exercise?

I meant to say, read it character by character until the end of line or null character. count the white space as an increment also.

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.