Writing a matrix in text file

I am trying to create a new text file and write a matrix value in it using fstream. But i am getting errors with this code. Would anyone please suggest me how to run it successfully?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <fstream>
#include <iostream>
#include <string>
#include <string.h>
#include <valarray>
#include <cstdlib>
#include <iomanip>

using namespace std;
using matrix = valarray< valarray<double> >;

matrix table={ {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}};

int main()
{

std::fstream myFile;
myFile.open("table.txt", ios_base::in|ios_base::out|ios_base::trunc);

if (myFile.is_open())
{

  std::cout <<"File open successful" <<endl;
  myFile << table <<endl;

   
myFile.close();
}
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <fstream>
#include <iostream>
#include <vector>
using namespace std;
using matrix = vector< vector<double> >;

ostream &operator << ( ostream &out, const matrix &M )
{
   for ( auto &row : M )
   {
      for ( auto e : row ) out << e << '\t';
      out << '\n';
   }
   return out;
}

int main()
{
   matrix table={ {0, 1, 2, 3, 4}, {1, 2, 3, 4, 0}, {2, 3, 4, 0, 1}, {3, 4, 0, 1, 2}, {4, 0, 1, 2, 3}, {0, 1, 2, 3, 4}};
   ofstream myFile( "table.txt" );
   cout << table;
   myFile << table;
}
Last edited on
@lastchance, many thanks!
I want to read the matrix from the text file after writing/overwriting it. Would you please suggest me how to do that? Thanks again.
Turn stream insertion (<<) into stream extraction (>>), turn off the const and the punctuation ('\t' and '\n'). That's about it if your matrix is of a known size.
Thank you, @lastchance.
To read the written matrix from the table.txt file, I wrote the following code, but it seems to me i did something wrong. First thing is in main() function, I should not write the first line (matrix table =...) because I just want to read the txt file and before reading i do not know these values. With below code, i also could not verify if it read correctly as it does not display the content it reads.

Would you please suggest me about this?

Second thing is, after reading the table.txt file, how i can move it to another matrix with same size?


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <fstream>
#include <iostream>
#include <vector>
using namespace std;
using matrix = vector< vector<double> >;

istream &operator >> ( istream &out, const matrix &M )
{
   for ( auto &row : M )
   {
      for ( auto e : row ) out >> e;
      //out >> '\n';
   }
   return out;
}

int main()
{
   matrix table={ {0, 0, 0, 0, 0.7}, {1, 2, 3, 4, 0}, {2, 3, 4, 0, 1}, {3, 4, 0, 1, 2}, {4, 0, 1, 2, 3}, {0, 1, 2, 3, 4}};
   ifstream myFile( "table.txt" );
   //cout << table;
   myFile >> table;
   //cout << table;

   
}
> using namespace std;
> using matrix = valarray< valarray<double> >;

I realise that nested valarrays have been repeatedly championed as a good idea in many posts here. However, it is best to avoid it; it is a violation of the requirement that the type of the element of the valarray must be a NumericType (valaray is permitted to throw std::bad_alloc) https://en.cppreference.com/w/cpp/named_req/NumericType

The standard recommends: "The illusion of higher dimensionality may be produced by the familiar idiom of computed indices, together with the powerful subsetting capabilities provided by the generalized subscript operators."

There are some other reasons too to stay away from valarrays:

cppreference: "expression templates make the same optimization technique available for any C++ container, and the majority of numeric libraries prefer expression templates to valarrays for flexibility."

Since it is rarely used in mainstream C++, writers of most C++ libraries consider it as a less important part of the library, even when it comes to bug-fixes.

On the plus side, valarrays do have a fairly natural, NumPy like, syntax for numeric operations.
@telco

- If the operation is input, you really shouldn't be calling the stream "out".
- Since the matrix is going to change then you shouldn't qualify it as "const".
- As the elements of the matrix are going to change you would need (noting the ampersand):
for ( auto &e : row ) in >> e;
rather than
for ( auto e : row ) in >> e;

All of this presupposes that your matrix size is already known.

If the matrix size is not known then you can either specify row and column counts within your input file or you could do the following. You are under no obligation to define operators << and >> for your input/output: you can just do the same with "normal" functions: that's up to you.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
using namespace std;
using matrix = vector< vector<double> >;

//======================================================================

ostream &operator << ( ostream &out, const matrix &M )
{
   for ( auto &row : M )
   {
      for ( auto e : row ) out << e << '\t';
      out << '\n';
   }
   return out;
}

//======================================================================

istream &operator >> ( istream &in, matrix &M )
{
   M.clear();                                          // Make sure M is empty
   for ( string line; getline( in, line ); )           // Read one line at a time
   {
      stringstream ss( line );                         // Put that line in a temporary stream
      vector<double> row;
      for ( double e; ss >> e; row.push_back( e ) );   // Stream the elements on that line into a new row
      M.push_back( row );                              // Add the row to the matrix
   }
   return in;
}

//======================================================================

int main()
{
   matrix table;
   ifstream inFile( "table.in" );
   ofstream outFile( "table.out" );

   inFile >> table;

   outFile << table;
   cout << table;
}



table.in
  1   2   3   4   5
 60  70  80  90 100
-11 -12 -13 -14 -15



table.out
1	2	3	4	5	
60	70	80	90	100	
-11	-12	-13	-14	-15	

Last edited on
Thank you, @lastchance. I tried to run it, but i did not get any output. My table.out file is empty and there is no table.in file.


Honestly, I could not understand the code. Would you please help me with following questions?
In the code, nowhere, the matrix values are given that i want to write, then how i can see the output? Do i have to type in matrix values in table.out file after running the code? Then which code sections belong to read the written matrix values and display what it reads?


The code(attached below) you suggested on 26th Jan to write a matrix is more easy for me to understand.
After writing the matrix in table.txt file, I want to
1. read it from the table.txt file
2. (after reading) save it in another matrix of same size or in other word, another matrix will take the same value of it. For example, matrix table1= matrix table
3. display table1

Would you please suggest me what i can add after the below code for that? Thank you.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <fstream>
#include <iostream>
#include <vector>
using namespace std;
using matrix = vector< vector<double> >;

ostream &operator << ( ostream &out, const matrix &M )
{
   for ( auto &row : M )
   {
      for ( auto e : row ) out << e << '\t';
      out << '\n';
   }
   return out;
}

int main()
{
   matrix table={ {0, 1, 2, 3, 4}, {1, 2, 3, 4, 0}, {2, 3, 4, 0, 1}, {3, 4, 0, 1, 2}, {4, 0, 1, 2, 3}, {0, 1, 2, 3, 4}};
   ofstream myFile( "table.txt" );
   cout << table;
   myFile << table;
}
Last edited on
@telco,
The file table.in is an input file - you are expected to create it (with a text editor) before running the program.

Also, you don't need to write and read from file just to copy one matrix to another! It uses standard containers, so, if table has already been defined, then you can simply write
matrix table2 = table;
Last edited on
Ok, thank you.
cppreference wrote:
expression templates make the same optimization technique available for any C++ container

Isn't this a bit misleading? No other container is allowed to use expression templates.
We are (a library is) allowed to create proxy objects and use expression templates with (adapted) standard containers. Wiki has a simplified example of using expression templates with std::vector<>
https://en.wikipedia.org/wiki/Expression_templates

Though it is much easier to use containers from a library like Eigen; ones which are designed from the ground up with the idea of using expression templates.
Topic archived. No new replies allowed.