How do you read two files in the same program in C++?

In summary, the task is to read two text files - one containing a square matrix and the other containing a vector - and multiply them together. The size of the matrix can vary from 1x1 to 10x10. The program must determine the size of the matrix and use a vector of vectors or dynamically allocated memory to store the data. The files are given in a specific format.
  • #1
Joon
85
2
Homework Statement
I want to read two different text files containing two different matrices in the same program then output the multiplication of the two. To read two different text files, do I need to close the first file then open the second file in the code? But then would the code that comes after (the multiplication code) work?
Relevant Equations
I'm trying to write a code that reads any square matrix from 1x1 to 10x10 using the format below.
My matrix text files can vary from 1x1 to 10x10 (Another file will be given when the code gets tested but it's all square matrices)
I'm stuck here.

C:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main() {

    const int MAXI = 10;
    int x, y, z, xcoordinates[MAXI], ycoordinates[MAXI], zcoordinates[MAXI], row1, column1, row2, column2, i, j, k;
    int A[3][3], B[3][1], C[3][1], i, count; 

    ifstream inFile("matrix(1).txt");

    i = 0;
    count = 0;
    while (inFile >> x >> y >> z) {

        xcoordinates[count] = x;
        ycoordinates[count] = y;
        zcoordinates[count] = z;
        count = count + 1;
    }

    }
 
Physics news on Phys.org
  • #2
Joon said:
My matrix text files can vary from 1x1 to 10x10 (Another file will be given when the code gets tested but it's all square matrices)
I'm stuck here.

C:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main() {

    const int MAXI = 10;
    int x, y, z, xcoordinates[MAXI], ycoordinates[MAXI], zcoordinates[MAXI], row1, column1, row2, column2, i, j, k;
    int A[3][3], B[3][1], C[3][1], i, count;

    ifstream inFile("matrix(1).txt");

    i = 0;
    count = 0;
    while (inFile >> x >> y >> z) {

        xcoordinates[count] = x;
        ycoordinates[count] = y;
        zcoordinates[count] = z;
        count = count + 1;
    }}
Yes, you can open more than one file for reading in your program. Just declare another ifstream variable.

C:
ifstream inFile1("matrix(1).txt");
ifstream inFile2("matrix(2).txt");

Read from each one just like you've already been doing.
 
  • #3
Alright, thank you.
I've tried to write the code to read the matrices but I don't think using xcoordinates[count], ycoordinates and zcoordinates is correct because I don't know what size the matrices are going to be. If it is 4 x 4 matrix, x y z is not enough since there's one more to take into account.

I know that for matrix multiplication, the column number of first matrix should match the row number of second matrix. Can I use this to write the code? How should I start the code in this case?
 
  • #4
try reading the files into a vector of vectors, then you can find the size of each to do the multiplication. Don't ask me how to do it off the top of my head, my favorite C++ book is at work, but it can be looked up pretty easily.
 
  • #5
Joon said:
My matrix text files can vary from 1x1 to 10x10
If this is all you know about the matrices, that makes it a bit harder.

One thing about C, and to some extent C++, is that an array size must be known when the program is compiled. Your program can't "discover" the matrix size, and then declare a two-dimensional array based on that size.

It is possible to allocate memory dynamically from the heap, but I don't know if you have covered that technique yet. C++ also has the STL (Standard Template Library) with containers that can grow in size at run time, but again, I don't know if that's something you know.

Has your instructor given you any hints?
 
  • #6
Mark44 said:
If this is all you know about the matrices, that makes it a bit harder.

One thing about C, and to some extent C++, is that an array size must be known when the program is compiled. Your program can't "discover" the matrix size, and then declare a two-dimensional array based on that size.
I don't see the problem here. If you know that the biggest size is 10x10, allocate for that and use a subarray.

@Joon: how is the file structured?
 
  • #7
with the vector class, you read the line and allocate it to a vector, all you need to know is the delimiter. Vectors can be of varying length, that is the usefulness of them. You then get the length easily and from there you write your matrix multiplication routine.
 
  • #8
DrClaude said:
I don't see the problem here. If you know that the biggest size is 10x10, allocate for that and use a subarray.
I thought of this, but didn't mention it, as it makes the program considerably more complicated.
DrClaude said:
@Joon: how is the file structured?
This is key to understanding the program's requirements.
 
  • #9
Sorry for the late reply. Actually the task is reading two text files (one with a square matrix and the other with a vector) and multiplying them. It is not two square matrices, it is one square matrix and one vector.
The text files are given as the matrix having 3 x 3 and the vector having 3 x 1. But this can vary when the code is tested.

I've been looking up the vector concepts and related problems on the internet but I find it quite difficult to get an idea of what to do. Most of the covered problems on the internet are using matrices of known sizes and often just ask to enter all the elements as cin.

Below is where I tried to start.
C:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main() {

    int row1, column1, row2, column2, i, j, k;
    int A[n][n], B[n][m], C[n][m], count;

    ifstream inFile1("matrix(1).txt");
    ifstream inFile2("vector(1).txt");

    n = 0;
 
 
    for (n=1; n=<10; n++){    }

So I have tried to use the fact that matrices can be multiplied only if the number of columns of the first matrix must match the number of rows of the second matrix and that the two multiplied lead to a n x m matrix above. What could I do from here?

I have no idea how to store the data in the text files so that I can use the data to multiply the matrix and the vector. I'll look into the delimeters.
 
Last edited:
  • #10
I think we need some clarification about what your class has studied so far, and about your assignment.

From your code so far, I can tell that you have studied C-style arrays, both one- and two-dimensional.

Have you also studied dynamic memory allocation using new() and delete(), or the C++ std::vector container? If not, then the statement in your first post that the matrices can be up to 10x10 indicates to me that you need to use the technique given by DrClaude: declare the matrix as 10x10, and then use only part of it.

Is the data file given to you, and you are not allowed to change its format? Or are you allowed to choose or modify the format to meet the needs of your program?

For example, it would be a lot easier to use DrClaude's technique, or dynamic memory allocation, if you can add a line to the beginning of the file that indicates the size of the matrix, e.g. for a 3x3 matrix:
Code:
3
11.0  12.0  13.0
21.0  22.0  23.0
31.0  32.0  33.0
 
  • #11
The data files are given to me. As mentioned the two files given contain a 3x3 square matrix and a 3x1 vector respectively, but when the code gets tested they'll give another file that can go up to 1x1 to 10x10 square matrix and the corresponding vector (1x1 to 10x1). I cannot edit the file as you did above, and I haven't learned the new and delete container.

Regarding the technique of declaring a 10x10 matrix, can I simply declare it as int A[10][10]? I want to know if I can use for or while loops, just like in my code above, to do the calculation as well.

EDIT: How can I set int A[10][10] as the matrix in the text file? Usually it's assigning elements like A[10][10] = { ... , ... , }
 
Last edited:
  • #12
Joon said:
EDIT: How can I set int A[10][10] as the matrix in the text file?
You can declare A to be a 10 x 10 matrix, like this:
C:
int A[10][10];
You can fill it with values from the text file like this:
C:
for (int i = 0; i < 10; i++)
{
    for (int j = 0; j < 10; j++)
        inFile >> A[i][j];
}
My example here is overly simplistic, since you can't be sure that there will be exactly 10 numbers on each line of the text file. You'll probably need some additional logic to determine when you run out of numbers on a line.
Joon said:
Usually it's assigning elements like A[10][10] = { ... , ... , }
This would be an error for multiple reasons. For the matrix I declared above, both indexes are in the range 0 ... 9. In addition, the syntax in your example has another problem. For example, A[2][5] represents a single number, not a list or tuple of numbers in braces.
 
  • #13
Right. Below is the fixed code.

C:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main() {

    int i, j;
    int A[10][10], B[10][10], C[10][10]; 

    ifstream inFile1("matrix(1).txt");
    ifstream inFile2("vector(1).txt");

    for (int i = 0; i < 10; i++) {

        for (int j = 0; j < 10; j++) {
            inFile1 >> A[i][j];
            inFile2 >> B[i][j];
        }
            
        
        
    }

I'm not sure if setting the matrices to [10][10] will work though. How can I show when the multiplication contains an error? For instance, the multiplication won't work if the two matrices are 1x3 , 2x2
 
  • #14
While you're reading the data file, you have to figure out the size of the matrix from the data that you're reading, and then fill your 2-dimensional array according. For example, if the file is like the one I posted before, but without the first line that says "3", you need to fill the array (call it A) so that:

A[0][0] = 11.0
A[0][1] = 12.0
A[0][2] = 13.0
A[0][3] = doesn't matter because you'll ignore it
...
A[0][9] = doesn't matter

A[1][0] = 21.0
A[1][1] = 22.0
A[1][2] = 23.0
A[1][3] = doesn't matter
...
A[1][9] = doesn't matter

A[2][0] = 31.0
A[2][1] = 32.0
A[2][2] = 33.0
A[2][3] = doesn't matter
...
A[2][9] = doesn't matter

A[3][0] = doesn't matter
...
A[3][9] = doesn't matter

The remaining rows will be like the A[3] row.

And then do all your matrix arithmetic using only the array elements that contain data that you've read in.

At this point it would help us if you tell us which kinds of input statements you know. I see you know the ">>" operator which you can use to read one number at a time from the file. Has your class studied any other input methods? E.g. the getline() function for strings, or C-style input using e.g. scanf() or fscanf()? I hope I've remembered the right names for the C-style functions because I've almost never used them in C++ myself.

The problem with ">>" here is that it doesn't distinguish between blank spaces, tabs, and newlines (end-of-lines), which are collectively called "white space". So if you have e.g. "inputfile >> a >> b;" it will read either

10.0 11.0

or

10.0
11.0

and set a = 10.0 and b = 11.0. Likewise if you split them into two statements, "inputfile >> a;" and "inputfile >> b;".

So you need some other method besides ">>" to find the end of a line!
 
  • #15
Yes I've covered getline and used it to read and discard the first line of a text file before (the header). But I haven't learned any C-style input methods. I've covered eof as well for the end of file.

Instead of storing each value (if it goes up to 10 x 10, the code will be too long), is there any other way of doing it?

For example, can I use a for loop within the arrays? From i=1 to 10 for the number of rows and j=1 to 10 for the number of columns
 
  • #16
Joon said:
Instead of storing each value (if it goes up to 10 x 10, the code will be too long), is there any other way of doing it?

For example, can I use a for loop within the arrays? From i=1 to 10 for the number of rows and j=1 to 10 for the number of columns
Yes, but don't run your indexes from 1 to 10. Instead, run them from 0 to 9. An array with 10 elements has indexes that run from 0 through 9.

The code you posted earlier has an error:
C:
for (int i = 0; i < 10; i++) {
        for (int j = 0; j < 10; j++) {
            inFile1 >> A[i][j];
            inFile2 >> B[i][j];
        }         
}
Matrix B should not be a two-dimensional array, since it is really just a (one-dimensional) vector. Each of the input lines in the inner loop runs 100 times, which is way too many for a vector with at most 10 elements. You're going to need two separate loop structures to read in the values -- one is a nested loop similar to the above to read the values in the text file into matrix A, and a non-nested loop to read the values from the text file into array B.

You also need to tell us how the values in the text file are arranged. Are the values for the two-dim. matrix arranged by lines? Are the values for the vector all on one line, or are they on separate lines?

As I mentioned before, you're likely going to need some logic in both loops to keep track of when you run out of data on a line.
 
  • #17
Text files are arranged just normally I would say, without any headers. They contain pure integer values only, please refer to the file attached. For matrix B, I think it might be replaced with a new one (when the code is tested) where the column number is not 1. Sorry for the confusion, since the multiplication will work as long as the number of columns of matrix 1 = the number of rows of matrix 2, a square matrix (the first one) nxn (n=<10) can be multiplied with the second one n x m where m is not necessarily 1.

I tried to use eof (end of file) in the code below. Please check if it's on the right track.

C:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main() {

    int i, j;
    int A[10][10], B[10][10], C[10][10];

    ifstream inFile1("matrix(1).txt");
    ifstream inFile2("vector(1).txt");

    for (int i = 0; i < 10; i++) {

        for (int j = 0; j < 10; j++) {
            inFile1 >> A[i][j];
            inFile2 >> B[i][j];
        }
           
    }

    while (!inFile1.eof()) {
        for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 10; j++) {
                inFile1 >> A[i][j];
                
            }
        }

       
    }
 

Attachments

  • matrix(1).txt
    56 bytes · Views: 344
  • #18
Below is the edited code. But the result seems wrong. What can I do to make the code read only until data runs out? So I've first set the matrices to 10 x 10 as shown below, but I want this code to work also for any size matrices. For example, if it's a 4x4 matrix out of 10x10 matrix times 4x4 matrix out of 10x10 matrix , what should I do to discard the remaining 6x6 non-data points?

C:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main() {

    int i, j, k, product;
    int A[10][10], B[10][10], C[10][10];

    ifstream inFile1("matrix(1).txt");
    ifstream inFile2("vector(1).txt");
    for (i = 0; i < 10; i++) {

        for (j = 0; j < 10; j++) {
            inFile1 >> A[i][j];
        }
    }    for (i = 0; i < 10; i++) {

        for (j = 0; j < 10; j++) {
            inFile2 >> B[i][j];
        }
    }

    // A*B yielding C
    for (i = 0; i < 10; i++) {

        for (j = 0; j < 10; j++) {
            product = 0;
            for (k = 0; k < 10; k++) {
                product = A[i][k] * B[k][j];
                C[i][j] = product;
            }
        }
    }

    for (i = 0; i < 10; i++) {
        for (j = 0; j < 10; j++) {
            cout << C[i][j];
        }
    }    system("pause");
}
 
  • #19
Some of your code is wrong, based on how you have described the program requirements in post #9.
joon said:
Actually the task is reading two text files (one with a square matrix and the other with a vector) and multiplying them.

If A is 10 x 10 and B is 10 x 1, the product will be a vector that is 10 x 1.
So,
1) Neither B nore C should be declared as matrices -- they should be declared as ordinary one-dim. arrays.
2) For reading B, you should NOT have a nested loop. In the nested loop below, you are attempting to read 100 values from the text file for an array that will hold at most 10 values.
C:
int A[10][10], B[10][10], C[10][10];
.
.
.
for (i = 0; i < 10; i++) {

        for (j = 0; j < 10; j++) {
            inFile2 >> B[i][j];
        }
    }
I mentioned before that you would need some logic to determine when you run out of data. Before going into possible approaches, could you post the exact wording of the problem statement, just in case there is some important information about the structure of the input files that you have left out.
 
  • #21
Now I have the correct code. It is shown below.
I want to use another for loop to read the matrix and the vector though, without declaring the size of the matrix and vector as [3][3] or [3]. Should I use something like count to do this?
C:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main() {

    int i, j, k;
    int A[3][3], B[3], C[3] = {}, transpose[3][3]; // Declaring the matrix, vector, product, and transpose matrix

    ifstream inFile1("matrix(1).txt"); //To read the text files
    ifstream inFile2("vector(1).txt");
    for (i = 0; i < 3; i++) {

        for (j = 0; j < 3; j++) {
            inFile1 >> A[i][j];
            transpose[j][i] = A[i][j]; //Using the concept of transpose matrix
            cout << transpose[j][i] << ' ';

        }
        cout << endl;
    }

    
    

    for (i = 0; i < 3; i++) {            inFile2 >> B[i]; //Vector 
        }
    

    // A*B giving C
    cout << "The product is" << endl;
    for (i = 0; i < 3; i++) {

            for (k = 0; k < 3; k++) {
                C[i] += A[i][k] * B[k]; //Vector multiplication
                
            }

            cout << C[i]; //Giving the product
            cout << endl; 
        }
    
    
            
        
        system("pause"); //To check the values
}
 
  • #22
@Joon, please show us the exact wording of the problem, on the off chance there is some important information that we don't have.

Several people have suggested declaring a two-D array of the largest possible size; e.g., int mat[10][10];
The problem with this is that if you have a text file with four lines of four numbers each, the first row of the array will be filled and the second row will be only partially filled.

One strategy I see, given what we know at this point and what the OP has already been exposed to, is to declare a one-D array with 10 elements, the largest possible vector (in the 2nd text file), and another one_D array with 100 elements. A while loop with a counter could be used to input values from the 2nd text file into the array, stopping when we reach end-of-file. When the loop exits, we will know the size of the vector (say vLen), and should also know the size of the square matrix in the first file; i.e., vLen * vLen. My assumption here is that if the vector has N elements, the matrix will have N x N elements, and that we don't need to guard against weird size mismatches.
 
Last edited:
  • #23
D'oh! I was so focused on trying to figure out the size of the matrix just by reading from that file, that I forgot about the second file with the vector! Yes, reading that file first as you described, will tell how big the matrix is. This assumes of course that one can count on them having matching sizes.

But in that method, why would one need a one-D 100-element array for the matrix, instead of a two-D 10x10 array? After the expected size of the matrix is known, surely one can read the matrix file and fill the appropriate part of the two-D array directly.
 
  • #24
jtbell said:
But in that method, why would one need a one-D 100-element array for the matrix, instead of a two-D 10x10 array? After the expected size of the matrix is known, surely one can read the matrix file and fill the appropriate part of the two-D array directly.
Yeah, that would work. I guess I was just thinking that a two-D 10 x 10 matrix is essentially the same as a one-D array with 100 elements, aside from some casts that you would need.
 

1. How do I open and read two files in the same C++ program?

To open and read two files in the same C++ program, you will need to use the ifstream class from the fstream library. This class allows you to open a file for input and read data from it. You will need to create two ifstream objects, one for each file you want to read from.

2. How do I specify the names and paths of the two files I want to read?

To specify the names and paths of the two files you want to read, you can use the open() function on each of your ifstream objects. This function takes in a string parameter that specifies the name and path of the file you want to open. Make sure to include the file extension in the name.

3. Can I read from both files simultaneously?

Yes, you can read from both files simultaneously by using a loop to read from each file one line at a time. You can also use the getline() function to read an entire line from each file at once.

4. How do I handle errors when opening and reading from two files?

You can handle errors when opening and reading from two files by using if statements to check if the files were successfully opened. If there is an error, you can use the fail() function to get the specific error message and handle it accordingly.

5. Do I need to close the files after I am done reading?

Yes, it is important to close the files after you are done reading to free up system resources. You can use the close() function on each of your ifstream objects to close the files. It is good practice to close the files even if you encounter an error while reading.

Similar threads

  • Engineering and Comp Sci Homework Help
Replies
15
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
14
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
2
Views
3K
  • Engineering and Comp Sci Homework Help
Replies
16
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
1
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
5
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
4
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
4
Views
2K
  • Programming and Computer Science
Replies
4
Views
3K
  • Engineering and Comp Sci Homework Help
Replies
7
Views
2K
Back
Top