0

Good day everybody, I'm beginner on C++. The aim I want to achieve is quiet silly. But I don't see/understand where is the mistake. I will be very thankfull with any bluecode help.

So... I want to assign the content of the file "REL", which is a matrix of 46x2 [no blank lines]:

28 28
28  6
28 21
28 30
28 16
22 22
22 33
22 9
39 39
39 32
39 46
39 10
39 24
36 36
36 7
36 43
36 23
11 11
11 26
11 41
15 15
15 17
15 45
15 29
15 40
3 3
3 37
3 42
3 34
3 2
35 35
35 4
35 14
35 44
35 18
13 13
13 12
13 25
13 5
13 1
13 8
13 31
20 20
20 27
20 19
20 38

and my C++ code is:

    include <stdlib.h>
    include <malloc.h>
    include <iostream>
    include <fstream>

    using namespace std;

    void allocateMatrix(int **& A, int row, int col)
    {
        int i;
        A = new int*[row];
        for (i=1; i<=col; i++)
            A[i] = new int[col];
    }

    void ReadData(int **& A, int row, int col) // read data from file
    {  
    int i,j;
    ifstream REL1;
    REL1.open ("REL");  // open file for reading                
    for(i=1;i<=row;i++)   // row loop
    {
        for(j=1;j<=col;j++)  // column loop
        {
            REL1 >> A[i][j]; // read data into matrix
        }
        REL1.close(); // close the file                
    }
    }

    void Display(int **& A, int row, int col) // display matrix
    { 
    int i,j;
    for(i=1;i<=row;i++)
    {
        for(j=1;j<=col;j++)
        { 
            cout << A[i][j] << "\t ";  // display numbers
        }
        cout << endl;
    }    
    }

    void Cero(int **& A, int row, int col) // display matrix
    {
    int i,j;
    for(i=1;i<=row;i++)
    {
        for(j=1;j<=col;j++)
        {
            A[i][j]=0;
        }
    }   
    }   

    int main()
    {
    int tm,rowR,colR,rowM,colM,**A,**B; 

    ifstream TM;
    TM.open("TM");
    TM >> tm;
    TM.close();

    rowR = rowM = colM = tm;
    colR = 2;

    allocateMatrix(A, rowM, colM);
    allocateMatrix(B, rowR, colR);
    Cero(A, rowM, colM); 
    //Display(A, rowM, colM);
    ReadData(B ,rowR, colR);
    Display(B, rowR, colR);

    }

and... when I run it in bash, the shell prompted to me:

28   28  
0    0   
Segmentation fault (core dumped)

Thanks in advance!!!

3
  • 1
    Unguarded input (like you >>) is a serious error. Had you checked its return value, you would have noticed that you're closing the file object far too often. Commented May 20, 2012 at 0:18
  • Thanks Kerrek SB, but I cannot realize "Unguarded input (like you >>) " Commented May 20, 2012 at 1:31
  • You mustn't just say REL1 >> A[i][j];, because that discards the vitally important return value of the operation. Instead, you need something like if (!(REL1 >> A[i][j])) { std::cerr << "Fatal error!\n"; std::exit(1); }. Commented May 20, 2012 at 9:56

4 Answers 4

3
for(i=1;i<=row;i++)   // row loop
{
    for(j=1;j<=col;j++)  // column loop
    {
        REL1 >> A[i][j]; // read data into matrix
    }
    REL1.close(); // close the file                
}

You're closing the file after reading the first line. Move the file closing line out of the loop.

for(i=1;i<=row;i++)   // row loop
{
    for(j=1;j<=col;j++)  // column loop
    {
        REL1 >> A[i][j]; // read data into matrix
    }               
}
REL1.close(); // close the file 
Sign up to request clarification or add additional context in comments.

3 Comments

Thnaks for the reply and I tested aswell, but the result is not encoraging... in shell it prompeted to me " ~/CM$ ./m2 Segmentation fault (core dumped) "
I'm not a master in C++, can you try to run the outer for loop to 10 or another number instead of "row", and watch the results? I think the problem's coming out from boundaries.
Thanks Ismet Alkan, and you are partially correct. I followed your advice and it display me more values. I tried with row = 10 and after row = 100 and it worked partially... the shell prompted to me **28 28 28 6 28 21 28 30 28 16 22 22 22 33 22 9 39 39 39 32 39 46 39 10 39 24 36 36 36 7 36 43 36 23 11 11 11 26 11 41 15 15 15 17 15 45 ** But... the list is the half and is not organize like a matrix [46*2] It seems that the data from file is not assigned by having in mind the matrix... just and array of one row
2

Array indices start at 0, not 1.

6 Comments

... and also the test in the for loop should use <, not <=
ok... I tested your suggestion and I still get " ~/CM$ ./m2 Segmentation fault (core dumped) " Thanks But I cannot still figure out the misplaced command... another different point of view to assume this properly? again Thanks in advance
Sure Mr @ScottHunter I posted it with all the comments, on this post, update. ` void ReadData(int & A, int row, int col) { int i,j; ifstream REL1; REL1.open ("REL"); for(i=0;i<row;i++) { for(j=0;j<col;j++) { REL1 >> A[i][j]; } } REL1.close(); } void Display(int **& A, int row, int col) { int i,j; for(i=0;i<row;i++) { for(j=0;j<col;j++) { cout << A[i][j] << "\t "; } cout << endl; } }` **REL file is on the original post and TR file only contain 46. Thanks in advance
@DavidAlejandro Please post the code by updating your original question. Then it will be formatted correctly :)
@DavidAlejandro: So you didn't change Cero or allocateMatrix?
|
0

Here's a typical, robust, albeit not perfectly optimal general method for reading input: Read each line first, and then parse each line into tokens. Length checking can be added of course so that you don't attempt to read a file with billions of lines, but I leave that to you.

Note that we never explicitly call close(), since that's not needed.

#include <iostream>
#include <sstream>
#include <iterator>  // for istream_iterator
#include <string>    // for getline and string
#include <vector>    // for vector
#include <cstdlib>   // for exit

namespace
{
    void die(int code, char const * msg)
    {
        std::cerr << msg << std::endl;
        std::exit(code);
    }
}

int main()
{
    std::ifstream tm("TM.txt");

    if (!tm) { die(1, "Could not open file."); }

    std::vector<std::vector<int>> matrix;

    for (std::string line; std::getline(tm, line); )
    {
        std::istringstream iss(line);
        std::vector<int> row(2);

        if (!(iss >> row[0] >> row[1])) { die(1, "Invalid line!"); }

        matrix.push_back(row);
    }

    // done, now use matrix[i][j]
}

In C++11 you could add various small optimisations, but never mind about that now. In a more general setting, you could also remove the restriction that each row consist of only two elements and instead read as many as there are, possibly checking the final size:

std::vector<int> row(std::istream_iterator<int>(iss), std::istream_iterator<int>());
// check that row.size() has the desired value!

Finally, you might like to add a counter to the outer loop and abort if there are more lines than expected (e.g. 46 in your case), so that you can't be sabotaged by a huge input file.

Comments

0

Thanks @KerrekSB for your response. This level of C++ programming is quiet one step ahead of basic knowledge of C++. Nevertheless, I tried your suggestion and rewrite the code as is posted:

#include <stdlib.h>
#include <malloc.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <iterator>  // for istream_iterator
#include <string>    // for getline and string
#include <vector>    // for vector
#include <cstdlib>   // for exit

using namespace std;

namespace
{
    void die(int code, char const * msg)
    {
        std::cerr << msg << std::endl;
    std::exit(code);
    }
}

void AllocateMatrix(int **& A, int row, int col)
{
int i;
A = new int*[row];
for (i=0; i<col; i++)
    A[i] = new int[col];
}

void ReadData(int **& A, int row, int col) // read data from file
{  
int i,j,in;
ifstream REL1;
REL1.open ("REL");  // open file for reading                
for(i=0;i<row;i++)   // row loop
{
    REL1 >> in; // read data into matrix
    for(j=0;j<col;j++)  // column loop
    {
        A[i][j]=in;
    }
}
REL1.close(); // close the file                
}

void Display(int **& A, int row, int col) // display matrix
{ 
int i,j;
for(i=0;i<row;i++)
{
    for(j=0;j<col;j++)
    { 
        cout << A[i][j] << "\t ";  // display numbers
    }
}
cout <<endl;    
}

void Cero(int **& A, int row, int col) // display matrix
{
int i,j;
for(i=0;i<row;i++)
{
    for(j=0;j<col;j++)
    {
        A[i][j]=0;
    }
}   
}   

int main()
{
int tm,rowR,colR,rowM,colM,**A,**B; 

ifstream TM;
TM.open("TM");
TM >> tm;
TM.close();

rowR = 46; 
rowM = colM = tm;
colR = 2;

AllocateMatrix(A, rowM, colM);
AllocateMatrix(B, rowR, colR);
Cero(A, rowM, colM); 
//Display(A, rowM, colM);
//ReadData(B ,rowR, colR);


std::ifstream rel("REL");
if (!rel) { die(1, "Could not open file."); }
std::vector<std::vector<int> > matrix;
for (std::string line; std::getline(rel, line); )
{
    std::istringstream iss(line);
    std::vector<int> row(2);
    if (!(iss >> row[0] >> row[1])) { die(1, "Invalid line!"); }
    matrix.push_back(row);
}




Display(B, rowR, colR);
}

And when I execute it, it prompet :

Invalid line!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.