0

I am writing a program in C++ that is supposed to locate 6 specific lines in an XML file, each line individually holding 25 numeric values, and then find the average of those 25 numeric values for each line separately and output that average to the console window and to an output file. Additionally, I am supposed to extract the 6 time-stamps associated with those 6 specific lines. So far I have been able to implement regex to find and extract and output the 6 time-stamps with success. However, the function to find the average of the 25 numerical wattage/voltage values in each of the 6 lines outputs nothing, despite there being no compiler errors. I've tried to rubber ducky debug my code to no avail, and was hoping that a fresh pair of eyes could point out what I'm doing wrong.

Expected output:

2014-07-08T18:14:17.716Z

2014-07-08T18:14:18.716Z

2014-07-08T18:14:19.716Z

2014-07-08T18:14:20.716Z

2014-07-08T18:14:21.716Z

2014-07-08T18:14:22.716Z

Average Voltage: 3924.76

Average Voltage: 5793.68

Average Voltage: 7149.2

Average Wattage: 19425.5

Average Wattage: 8799.4

Average Wattage: 12602.9

Current Output:

http://imgur.com/JmKnF0o

XML file: http://pastebin.com/5hMy9RzK

#include <fstream>
#include <string>
#include <iostream>
#include <regex>
void timestamps();
void voltAvg();
using namespace std;
float sum; //global variable
ifstream infile;
ofstream outFile;

int main(){
outFile.open("Outputdata.txt");
infile.open("Groupproject.xml"); // Opens the XML file containing the information that is to be read
if (infile.fail())
{
    cout << "The file is not able to be located" << endl;
    system("Pause");
    exit(1);
}
timestamps();
voltAvg();
infile.close();
outFile.close();
system("pause");
return 0;
}


void timestamps() {
string fileinput;

regex time_regex("\\d\\d\\d\\d-\\d\\d-\\d\\d\\w\\d\\d:\\d\\d:\\d\\d\\.716Z");
smatch time_matches;



while (!infile.eof()) {  //Until the end of the file is reached, obtain each line
    getline(infile, fileinput);

    if (regex_search(fileinput, time_matches, time_regex)) { // if regex_search is able to locate a line which has elements matching the regex expression "time_regex" output the located element

        cout << "Timestamp: " << time_matches[0] << endl;
        outFile << "Timestamp: " << time_matches[0] << endl;
}

}

}

void voltAvg() {
float ave;
float dataValues;
int index;
string s;
string locateWord;

getline(infile, s); //gets first line of file
index = s.find(' '); //finds first white space
locateWord = s.substr(0, index); //cuts up line and assigns to locateWord
while (locateWord != "<VoltAmpereReactiveTimeSeries")
{
    getline(infile, s);
    index = s.find(' ');
    locateWord = s.substr(0, index);

}
    s = s.substr(index + 1, s.length());
    infile.ignore(116, '\n'); // Ignores all of the stuff on the "<VoltAmpereReactiveTimeSeries" line and gets to the numbers on the subsequent line

    for (int i = 0; i < 3; i++) {
        for (int count = 0; count < 25; count++) //sums 25 voltage/wattage values
        {
            infile >> dataValues;//extract voltage data values from InFile
            sum += dataValues;
        }
        ave = sum / 25.0; //calculate the average voltage
        cout << "Average Voltage: " << ave  << endl;//outputs ave on screen
        outFile << "Average Voltage: " << ave << endl; //Prints the average to out file
        sum = 0; // re initialize sum 
        infile.ignore(176, '\n'); 

    }
    for (int j = 0; j < 3; j++) { 
        for (int countb = 0; countb < 25; countb++) //sums 25 voltage/wattage values
        {
            infile >> dataValues;//extract wattage data values from infile
            sum += dataValues;
        }
        ave = sum / 25.0; //calculate the average wattage
        cout << "Average Wattage: " << ave << endl;//outputs ave on screen
        outFile << "Average Wattage: " << ave << endl; //Prints the average to out file
        sum = 0; // re initialize sum 
        infile.ignore(176, '\n');

    }
}
Mrcitrusboots
  • 197
  • 1
  • 11
  • `while (!infile.eof())` Already we have an issue: http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong Also, why not use an XML parser instead of trying to do this yourself? – PaulMcKenzie Dec 08 '15 at 02:01
  • Don't do `while (!infile.eof())`, it will not work as you expect. Instead do e.g. `while (std::getline(...))`. – Some programmer dude Dec 08 '15 at 02:02

1 Answers1

1

The problem is that once the timestamps function returns, the file is at the end, so when the voltAvg function tries to read from the file it's already at the end. You need to "rewind" the file between the calls by using the seekg function.

This would be very evident if you actually checked the stream status, by doing e.g. while (getline(...)) instead in the voldAvg function.

Some programmer dude
  • 363,249
  • 31
  • 351
  • 550
  • Thank you, `seekg` wasn't in my knowledge-bank. However, it is now! Thanks! – Mrcitrusboots Dec 08 '15 at 02:13
  • Actually, if it's not too much of a bother there is one minor hiccup left. While my program is now actually outputting 6 averages for each of the 6 lines as I intended it to, I am not obtaining the averages I want. E.G: http://imgur.com/kabVeX8 Here's my code currently: https://gist.github.com/anonymous/acfe6633f8b8d56ec2e2 – Mrcitrusboots Dec 08 '15 at 02:34