0

I am processing a .txt file of format shown below:

Header 1:\n Header 2: \n 1 \n 2 \n 3 \n Header 1a: \n ...

And my code is as follows:

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>

using namespace std;

int main(int argc, char* argv[])
{
    ifstream infile(argv[1]);

    string file_name = argv[1];
    int after_underscore = 0;
    string cut_name;
    for (int i = 0; i < file_name.length(); i++) {

        if (!ispunct(file_name[i])) {
            cut_name += file_name[i];
        }
        else
            break;
    }

    ofstream outfile(cut_name + std::string("_processed.txt"));
    cout << "Processing " << argv[1] << "..." << endl;

    string line;
    int header_no = 7; // change this if the number of headers in the txt file changed
    size_t points_no = 0; // this is the number of recorded points for each entry
    size_t no_of_events = 0;

    // define the needed header
    string header1 = "Record Length";
    string header2 = "Event Number";

    size_t foundHeader1, foundHeader2 = 0;
    while (!infile.eof()) {
        // to process the header
        for (unsigned int i = 0; i < header_no; i++) {
            getline(infile, line);
            foundHeader1 = line.find(header1);
            foundHeader2 = line.find(header2);
            int found_colon = line.find(":");
            // looking for the "Record Length " header and find the number of points recorded
            // Also look for "Event Number" header and count how many events are recorded
            if (foundHeader1 != string::npos) {
                line = line.substr(found_colon + 1);
                points_no = stoi(line);
                continue;
            }
            else if (foundHeader2 != string::npos) {
                no_of_events += 1;
                continue;
            }
            else
                continue;
        }
    }
    infile.close();
    infile.clear();
    // to process the numbers
    outfile << "Number of points per entry: " << points_no << endl;
    outfile << "Number of events recorded: " << no_of_events << endl;
    outfile << endl;
    infile.open(argv[1]);

    while (infile) {
        cout << "Hello" << endl;
        for (unsigned int i = 0; i < header_no; i++) {
            getline(infile, line);
        }
        for (unsigned int i = 0; i < points_no; i++) {
            getline(infile, line);
            outfile << line << " ";
        }
        outfile << endl;
    }
    outfile.close();

    cout << "Done processing! " << cut_name << "_processed.txt is produced" << endl;
}

The code gives me the correct output, but I noticed that there are some white spaces added in the output file towards the end of my output. enter image description here

I wanted my entries to end after "730 \n" but oddly some white spaces are added after then and an extra \n is there too. These white spaces are unwanted and gave me issues when I want to further process the output file. I could not figure out why they are present there. Can anyone help me to check what went wrong or give me some advise? Thanks you.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
cZe99
  • 13
  • 5
  • 1
    have mercy and use clang format. Edit: Ok I did it for you. – Marek R Sep 30 '21 at 17:41
  • 2
    Using things like `while(!infile.eof())` and `while (infile)` while ignoring the return value of `getline` is not the best strategy. – Retired Ninja Sep 30 '21 at 17:44
  • 2
    `while (!infile.eof())` common newbie mistake. https://stackoverflow.com/a/5605159/1387438 – Marek R Sep 30 '21 at 17:46
  • 1
    Pro tip: Break your program down into smaller pieces, let's call them functions, that does one particular thing - and does it well. Reading your code and debugging your code becomes a lot easier. – Ted Lyngmo Sep 30 '21 at 17:49
  • 1
    Please provide [mcve]. This should cover: smallest input file reproducing issue, expected outcome and actual outcome (note it is not clear what you are expecting as a result). Also I would strongly recommend slice this code into smaller functions. It would be best if it is done in such way, that it is easy to replace file streams with standard input/output streams. This way online compilers could be used. – Marek R Sep 30 '21 at 17:50
  • 2
    When the input fails, the code ignores the failure and carries on as if the input had succeeded. Hilarity and hijinks ensue. – Eljay Sep 30 '21 at 17:51
  • `for (unsigned int i = 0; i < header_no; i++) {` -- `for (unsigned int i = 0; i < points_no; i++)` -- You are assuming that `header_no` and `points_no` are correct, since inside those loops, you are using `getline`. What if either or both of those values are not correct? I really didn't care about the input file stuff, it's the output file writing I focused on, and that is a glaring issue that you need to check. – PaulMcKenzie Sep 30 '21 at 17:53
  • 1
    if you use a `std::istringstream ss{" ... put contents of file here ..."};` in place of the `ifstream` you need not change the code but can present a complete reproducible exmaple – 463035818_is_not_an_ai Sep 30 '21 at 17:59

0 Answers0