Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Cumulative total for each device 1

Status
Not open for further replies.
Apr 8, 2014
13
0
0
US
I have iostat output in a file and need a cumulative total for each device (there may be a few or there could be tens of devices).
for example:
Code:
sdy 1.0
sdz 1.0
sdy 17.5
sdz 12.1
sdy 5.33
sdz 0.3

This can be done like this in awk using:
Code:
awk '{await[$1]+=$10}END{for(j in await)print j" "await[j]}' x

How can this be done using C to get output like:
Code:
sdy 19.18
sdz 14.19
 
IMO, it's about using associative arrays in C.
 
For this purpose std::map from C++ can be used:

data_proc.c
Code:
[COLOR=#0000ff]// Compile Command:[/color]
[COLOR=#0000ff]// g++ data_proc.c -o data_proc[/color]

[COLOR=#a020f0]#include [/color][COLOR=#ff00ff]<iostream>[/color]
[COLOR=#a020f0]#include [/color][COLOR=#ff00ff]<fstream>[/color]
[COLOR=#a020f0]#include [/color][COLOR=#ff00ff]<iomanip>[/color]
[COLOR=#a020f0]#include [/color][COLOR=#ff00ff]<map>[/color]

using namespace std;

[COLOR=#2e8b57][b]void[/b][/color] process_data([COLOR=#2e8b57][b]void[/b][/color]);

[COLOR=#2e8b57][b]int[/b][/color] main() {
  [COLOR=#2e8b57][b]char[/b][/color] dev_name[[COLOR=#ff00ff]4[/color]];
  [COLOR=#2e8b57][b]double[/b][/color] dev_size;
  std::map<string, [COLOR=#2e8b57][b]double[/b][/color]> totals;
  std::map<string, [COLOR=#2e8b57][b]double[/b][/color]>::iterator totals_it,totals_end;
  
  [COLOR=#2e8b57][b]FILE[/b][/color]* file = fopen([COLOR=#ff00ff]"data.txt"[/color],[COLOR=#ff00ff]"r"[/color]); 

  cout << [COLOR=#ff00ff]"Reading Data :"[/color] << endl;
  [COLOR=#804040][b]while[/b][/color](fscanf(file, [COLOR=#ff00ff]"[/color][COLOR=#6a5acd]%s[/color][COLOR=#ff00ff] [/color][COLOR=#6a5acd]%lf[/color][COLOR=#ff00ff]"[/color], dev_name, &dev_size) != [COLOR=#ff00ff]EOF[/color]) {
    [COLOR=#0000ff]// print line[/color]
    cout << [COLOR=#ff00ff]"dev_name = '"[/color] << dev_name << [COLOR=#ff00ff]"', dev_size = "[/color] 
         << std::fixed << std::setw([COLOR=#ff00ff]5[/color]) << std::setprecision([COLOR=#ff00ff]2[/color]) 
         << dev_size << endl;
    [COLOR=#0000ff]// process data;[/color]

    [COLOR=#804040][b]if[/b][/color](totals[dev_name]) {
      totals[dev_name] += dev_size;
    }
    [COLOR=#804040][b]else[/b][/color] {
      totals[dev_name] += dev_size;
    }
  }
  [COLOR=#0000ff]// close file[/color]
  fclose(file);

  [COLOR=#0000ff]// print results[/color]
  cout << endl << [COLOR=#ff00ff]"* Totals :"[/color] << endl;
  [COLOR=#804040][b]for[/b][/color]( totals_it = totals.begin(), totals_end = totals.end();  
       totals_it != totals_end;  totals_it++ )  {
       cout <<  totals_it->first << [COLOR=#ff00ff]" : "[/color] << totals_it->second << endl;
  }
  
  [COLOR=#0000ff]// at end return[/color]
  [COLOR=#804040][b]return[/b][/color]([COLOR=#ff00ff]0[/color]);
}

Output:
Code:
$ g++ data_proc.c -o data_proc

$ data_proc
Reading Data :
dev_name = 'sdy', dev_size =  1.00
dev_name = 'sdz', dev_size =  1.00
dev_name = 'sdy', dev_size = 17.50
dev_name = 'sdz', dev_size = 12.10
dev_name = 'sdy', dev_size =  5.33
dev_name = 'sdz', dev_size =  0.30

* Totals :
sdy : 23.83
sdz : 13.40
 
In the code above, there is a little typo in the assigning value to the associative array:
Code:
...
else {
  totals[dev_name] [highlight]+=[/highlight] dev_size;
}
...
It should be
Code:
...
else {
  totals[dev_name] [highlight]=[/highlight] dev_size;
}
...
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top