Problem with Reading data from txt file

Hello everyone,
I am tring to read data from a txt file and the data looks like that:

cap=[1332 100 120 130 12 13 2 1 32 21 1332 1332 1332 1332 1332 1332 1332 1332 1332 1332];

Here is the code to read it:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  	char c;
	if (file.is_open())
	{
		file >> c>>c>>c>>c>>c;
		for (int i = 0; i < nbPeriod; i++) file>>c>>cap[i];
		file >> c;
	}
	else
	{
		cerr << "File or stream not valid.\n";
		//	return 1;
	}
	for (int i = 0; i < nbPeriod; i++) cout << cap[i] <<'\t';
	cout << "\n\n";


What I get:
332 0 20 30 2 3 1 2 1 332 332 332 332 332 332 332 332 332 332 0

How can I correct it? Thank you in advance
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
using namespace std;

int main()
{
// ifstream in( "data.txt" );
   istringstream in( "cap=[1332 100 120 130 12 13 2 1 32 21 1332 1332 1332 1332 1332 1332 1332 1332 1332 1332]; " );

   string line;
   getline( in, line, '[' );   getline( in, line, ']' );
   stringstream ss( line );

   vector<int> cap;
   for ( int i; ss >> i; ) cap.push_back( i );

   for ( auto e : cap ) cout << e << ' ';
}


1332 100 120 130 12 13 2 1 32 21 1332 1332 1332 1332 1332 1332 1332 1332 1332 1332 
Last edited on
Thank you so much @lastchance. To be honest, I tried this "getline " way. It works for me for the single line data like our cap=[1......] in the example. However, I have another data called x in the following form
x=[[5 7 4 ],
[3 3 3],
[1 2 5],]; I do know how to use getline to read this type of 2D matrixes. That's why I had tried to read it by char c as in my question? I haven't too much knowledge about using getlne, can I read 2D matrices as in this x matrix example ? How can I do that ? Thank you so much
@learner999,
unless you show the precise form of the input file it is impossible to advise you.

How to read files is invariably premised on the format they were written to in the first place.

What exactly does your input file look like? (Please put it in output tags from the formatting menu.)

Thank you @lastchance. Here how it looks like :
I hope I can use tags correctly..

T=20;
cap=[1332 1332 1332 1332 1332 1332 1332 1332 1332 1332 1332 1332 1332 1332 1332 1332 1332 1332 1332 1332];
f=[[37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37],
[37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37],
[25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25],
[75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75],
[62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62],
[37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37],
[75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75],
[37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37],
[25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25],
[62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62],
];


Thank you so much
Last edited on
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

using matrix = vector<vector<int>>;

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

bool readSomething( istream &in, string &item )
{
   return (bool)getline( in >> ws, item, ';' );
}

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

char parseSomething( const string &item, string &name, int &S, vector<int> &V, matrix &M  )
{
   char ctype, c;
   S = 0;
   V.clear();
   M.clear();

   // Get the type
   int n = count( item.begin(), item.end(), '[' );
   if      ( n == 0 ) ctype = 's';   // scalar
   else if ( n == 1 ) ctype = 'v';   // vector
   else               ctype = 'm';   // matrix

   stringstream ss( item );
   getline( ss, name, '=' );

   switch ( ctype )
   {
      case 's':
         ss >> S;
         break;

      case 'v':
         ss >> c;
         for ( int i; ss >> i; ) V.push_back( i );
         break;

      case 'm':
         ss >> c;
         for ( int r = 0; r < n - 1; r++ )
         {
            ss >> c;
            string row;
            getline( ss, row, ']' );
            ss >> c;
            stringstream srow( row );
            for ( int i; srow >> i; ) V.push_back( i );
            M.push_back( V );
            V.clear();
         }
   }

   return ctype;
}

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

int main()
{
   ifstream in( "data.txt" );
   int S;
   vector<int> V;
   matrix M;

   for ( string item, name; readSomething( in, item ); )
   {
      switch ( parseSomething( item, name, S, V, M ) )
      {
         case 's':
            cout << "Scalar: " << name << '\n';
            cout << S;
            break;
         case 'v':
            cout << "Vector: " << name << '\n';
            for ( auto e : V ) cout << e << ' ';
            break;
         case 'm':
            cout << "Matrix: " << name << '\n';
            for ( auto &row : M ) 
            {
               for ( auto e : row ) cout << e << ' ';
               cout << '\n';
            }
      }
      cout << "\n\n";
   }
}


Scalar: T
20

Vector: cap
1332 1332 1332 1332 1332 1332 1332 1332 1332 1332 1332 1332 1332 1332 1332 1332 1332 1332 1332 1332 

Matrix: f
37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 
37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 
25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 
75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 
62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 
37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 
75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 
37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 
25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 
62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 



Thank you so much @lastchance. You really taught me a lot. Actually, I want to read this data to process them. In the following parts of my code, I will , for example , change a value in a certain index of matrix f ,for example f[2][2] will be changed. So, in your position, which part I should modify to assign readed matrix to a certain array ?

I will define a vector ;

vector<vector<double>>f; and when I read the data , it will be the content of array f. In your previous answer, you had proposed:
vector<int> cap;
for ( int i; ss >> i; ) cap.push_back( i );

It is working super fine. Just I need the array version of it when the matrix is read ib the data file?

The second thing in your latest proposition, the example I sent all the values are integer. What should we do if the matrix include float values?
I know I might ask too much but this reading data file issue is always an issue for me , I am on this task for three days , so I need to learn as much as I can

Thank you so much again.
learner999,
I think there is enough in the program that I wrote to take it from there. It is not a major issue to switch from a container storing int to one storing double.
Thank you so much @lastchance. I solved the switching issue from int to float. However, I still do not know how can I store the values read in an array or as integer varible . The code reads name and says Matrix "cap " but that "cap " must be the variable or vector name for me . Basically the string variable must be converted to integer name or vector name. I do not know if it is possible in c++ . maybe I think more complicated way, maybe there is an easier way ..In current case , for example I can not address f[2][2]=100 in the following of the code. Because f matrix is not defined.
Last edited on
@learner999,
I don't understand your question.

The function
char parseSomething( const string &item, string &name, int &S, vector<int> &V, matrix &M )
simply takes item (which is whatever was read from file up to each semicolon) and converts it into either:
- the variable S if it is a scalar
- the variable V if it is a vector
- the variable M if it is a matrix
It then returns 's', 'v' or 'm' as a char to tell the user what it found.

The variable name is simply set to whatever it was called in the data file. Use it or not as you choose.

Just use whichever of S, V or M you need for your variable after calling this routine.


I only wrote it like this to try to protect myself from any changes to the question by keeping it as general as possible. Obviously, in the case of <int> vs <double> I failed.
Last edited on
Is this what you wanted?

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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

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

bool readSomething( istream &in, string &item )
{
   return (bool)getline( in >> ws, item, ';' );
}

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

template<typename T>
char parseSomething( const string &item, string &name, T &S, vector<T> &V, vector< vector<T> > &M  )
{
   char ctype, c;
   S = 0;
   V.clear();
   M.clear();

   // Get the type
   int n = count( item.begin(), item.end(), '[' );
   if      ( n == 0 ) ctype = 's';   // scalar
   else if ( n == 1 ) ctype = 'v';   // vector
   else               ctype = 'm';   // matrix

   stringstream ss( item );
   getline( ss, name, '=' );

   switch ( ctype )
   {
      case 's':
         ss >> S;
         break;

      case 'v':
         ss >> c;
         for ( T i; ss >> i; ) V.push_back( i );
         break;

      case 'm':
         ss >> c;
         for ( int r = 0; r < n - 1; r++ )
         {
            ss >> c;
            string row;
            getline( ss, row, ']' );
            ss >> c;
            stringstream srow( row );
            for ( T i; srow >> i; ) V.push_back( i );
            M.push_back( V );
            V.clear();
         }
   }

   return ctype;
}

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

template<typename T>
void printMatrix( const vector< vector<T> > &M, int width )
{
   for ( auto &row : M )
   {
      for ( auto e : row ) cout << setw( width ) << e << ' ';
      cout << '\n';
   }
}

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

int main()
{
   ifstream in( "data.txt" );
   double S;
   vector<double> V;
   vector< vector<double> > M;

   string item, name;
   for ( int thing = 0; thing < 3; thing++ )
   {
      readSomething( in, item );
      parseSomething<double>( item, name, S, V, M );
      cout << "Read " << name << '\n';
   }
   
   // Assuming the given data file then the last thing read is the matrix F; either use M or make a copy
   auto F = M;
   
   F[2][2] = 100;        // or whatever

   // Check
   cout << "\nPrinting modified matrix:\n";
   printMatrix( F, 3 );
}


Read T
Read cap
Read f

Printing modified matrix:
 37  37  37  37  37  37  37  37  37  37  37  37  37  37  37  37  37  37  37  37 
 37  37  37  37  37  37  37  37  37  37  37  37  37  37  37  37  37  37  37  37 
 25  25 100  25  25  25  25  25  25  25  25  25  25  25  25  25  25  25  25  25 
 75  75  75  75  75  75  75  75  75  75  75  75  75  75  75  75  75  75  75  75 
 62  62  62  62  62  62  62  62  62  62  62  62  62  62  62  62  62  62  62  62 
 37  37  37  37  37  37  37  37  37  37  37  37  37  37  37  37  37  37  37  37 
 75  75  75  75  75  75  75  75  75  75  75  75  75  75  75  75  75  75  75  75 
 37  37  37  37  37  37  37  37  37  37  37  37  37  37  37  37  37  37  37  37 
 25  25  25  25  25  25  25  25  25  25  25  25  25  25  25  25  25  25  25  25 
 62  62  62  62  62  62  62  62  62  62  62  62  62  62  62  62  62  62  62  62 

Topic archived. No new replies allowed.