Read data from text file

Hi everyone:
I have to read some data from the text file :

transmission number for node 1 is : 23 The TxEnergy used is : 223 PJ
transmission number for node 4 is : 11 The TxEnergy used is : 543 PJ
transmission number for node 7 is : 23 The TxEnergy used is : 568 PJ
transmission number for node 5 is : 22 The TxEnergy used is : 114 PJ
transmission number for node 6 is : 53 The TxEnergy used is : 657 PJ
transmission number for node 3 is : 23 The TxEnergy used is : 898 PJ
transmission number for node 8 is : 23 The TxEnergy used is : 178 PJ
transmission number for node 2 is : 23 The TxEnergy used is : 432 PJ
transmission number for node 1 is : 23 The TxEnergy used is : 111 PJ
transmission number for node 4 is : 52 The TxEnergy used is : 123 PJ
transmission number for node 7 is : 23 The TxEnergy used is : 222 PJ
transmission number for node 5 is : 31 The TxEnergy used is : 367 PJ
transmission number for node 6 is : 17 The TxEnergy used is : 726 PJ
transmission number for node 3 is : 25 The TxEnergy used is : 452 PJ
transmission number for node 8 is : 23 The TxEnergy used is : 563 PJ
transmission number for node 2 is : 23 The TxEnergy used is : 736 PJ

I would like to extract the max values for each node but my program prints me just the max for node number 1 eight times:

223 223 223 223 223 223 223 223

Given the input data I expect to see:

223 736 898 543 367 726 568 563


This is my code :

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <algorithm>
#include <vector>
#include <string>
#include <numeric>
using namespace std;
template <typename T>
string IntToString(T Number)
{ stringstream ss;
ss <<Number;
return ss.str();
}
int main() {
ifstream ifs;
ofstream ofs;
double maxTxEnergy = 0;
vector<double> TxE;
double maxRxEnergy = 0;
double FullTxEnergy = 0;
double FullRxEnergy = 0;
for (int i = 1; i <=1; i++){
stringstream ss;
ss <<i<<"00";
string filename = ss.str();
filename.append(".txt");
ifs.open(filename.c_str());
cout << "Analyzing: " << filename << endl;
string filename1 = "Result/";
filename1.append(filename);
ofs.open(filename1.c_str());
string str;
for (int j=1; j<=8; j++)
{
string s = IntToString(j);
while (!ifs.eof()) {
getline (ifs, str);
int a = str.find("transmission number for node "+s+" is :");
if (a != -1) {
double TxEnergy = 0;
istringstream iss(str.substr(a+62));
iss >> TxEnergy;
maxTxEnergy = TxEnergy;
if(maxTxEnergy<TxEnergy)
maxTxEnergy = TxEnergy;
}

}
TxE.push_back(maxTxEnergy);

}
for (std::vector<double>::iterator it = TxE.begin(); it != TxE.end (); it++)
{
ofs << "Full transmission Energy: " << *it << endl;
}
ifs.close();
ofs.close();
}
return 0;
}


Any Help,
The while loop
1
2
while (!ifs.eof()) {
getline (ifs, str);
ensures that the file is read through to the end on the first pass of the for loop. You could probably get your code to work by clearing the ifs flags and resetting the position to the start before each pass of the for loop.

Alternatively, you might do what you need on a single pass of the file.

Here, I've used a std::map instead of a vector, in order to store the max energy associated with each node.
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
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <algorithm>
#include <map>
#include <string>
#include <numeric>

using namespace std;

template <typename T>
string IntToString(T Number)
{   
    stringstream ss;
    ss <<Number;
    return ss.str();
}

int main() 
{
    ifstream ifs;
    ofstream ofs;

    std::map<int, double> TxE;
    std::map<int, double>::iterator it;
    
    for (int i = 1; i <=1; i++)
    {    
        stringstream ss;
        ss << i << "00";
        string filename = ss.str();
        filename.append(".txt");
        ifs.open(filename.c_str());
        if (!ifs)
        {
            cout << "Input file " << filename << " not open\n";
            break; 
        }
        
        cout << "Analyzing: " << filename << endl;
    
        string filename1 = "Result/";
        filename1.append(filename);
        ofs.open(filename1.c_str());
        if (!ofs)
        {
            cout << "Output file " << filename1 << " not open\n";
            break; 
        }       
    
        string stemp;     
            
        while (getline (ifs, stemp))
        {        
            if (stemp.find("transmission number for node") != string::npos) 
            {
                double TxEnergy = 0;
                int node;
                istringstream iss(stemp.substr(28, 3));
                iss >> node;

                iss.str(stemp.substr(62));                  
                iss >> TxEnergy;

                it = TxE.find(node);

                if (it == TxE.end())
                {
                    TxE[node] = TxEnergy;
                }
                else
                {
                    if (it->second < TxEnergy)
                        TxE[node] = TxEnergy;
                }
            }  
        }

        for (it = TxE.begin(); it != TxE.end (); it++)
        {
            ofs << "Full transmission Energy: " << it->second << endl; 
        }          
        
        ifs.close();
        ofs.close();
    }
    
    return 0;
}


By the way I renamed the string from str to stemp simply because this line was starting to look confusing with two different uses of str:
 
    iss.str(stemp.substr(62)); 

Last edited on
thank you very much for your response Chervil ; normally it works with your proposition.mais now I have to calculate the sum of the Energy for each node that is to say instead of calculating the max I'll calculate the sum; I have try with std :: accumulate but it not work, your help
Perhaps you didn't understand the code I showed last time:
66
67
68
69
70
71
72
73
74
75
76
    it = TxE.find(node);               // Does the node already exist?

    if (it == TxE.end())
    {
        TxE[node] = TxEnergy;          // No. Simply store the value.
    }
    else
    {
        if (it->second < TxEnergy)     // Yes. Store the value only if larger than saved value.
            TxE[node] = TxEnergy;
    }


As you can see, instead of comparing the value at line 75, all you need to do is to add to it.

Actually it can be simplified. The std::map operator[] will either insert a new element with the default value (zero in this case) or return a reference to the existing element.

Thus it is sufficient to put simply TxE[node] += TxEnergy; in the place of that entire block from lines 66 to 76.

Please see the reference page for more information:
http://www.cplusplus.com/reference/map/map/operator%5B%5D/


Last edited on
thank you very much for your Help Chervil ; now it works ;) ;)
Topic archived. No new replies allowed.