Issues when calling to a function, C++

Viewed 33

I need help please.

I made a code which purpose is to modify a value at a specific place in a .txt. My first idea was to store all my .txt in a vector, then to deal with that vector.

For that I created 2 functions : One is basically splitting a line of the .txt, the other one is to find the good line in the txt., when found, the line is splitted by calling the first and then I can modify the value for the wanted one.

Well more or less, you can read my code following :

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstdlib>

using namespace std;

vector<string> split(string myData) {
    vector<string> temporary;
    string delim = " ";
    string buf= "";
    int i = 0;
    while (i < myData.length()) {
        if (myData[i] != delim)
            buf += myData[i];
        else if (myData[i] == delim) {
            if (buf != ""){temporary.push_back(buf);}
            buf = "";
        } 
        i++;
    }
    return temporary;
}

void test (){
    fstream yourfile;
    string line, someString;
    vector<string> fichier;
    someString = "EnergySampler";
    ofstream monflux("/Users/geant4_simulation_20210413/results/myFile1MeV.txt");
    ifstream myFile("benchmark.txt");
    double number;
    
//////STORING THE .TXT IN VECTOR    
    
    if (myFile){
        while (getline(myFile,line)){
            fichier.push_back(line);
        } //end while
    } //end if
    else cerr << "Your file couldn't be opened";
     
////LOOKING FOR THE LINE AND MODIFY IT    

    for (int i(0); i<fichier.size(); i++) {
        size_t found = fichier[i].find(someString);
        if(found != string::npos){ // si existe
            //cout << fichier[i] << endl;
            vector<string> splitted ;
            splitted=split(fichier[i]);      // problem here...
            cout << splitted.size() <<endl;
            
            
            for (int k = 0; k < splitted.size(); k++){
                //number = strtod(splitted[k],&end);
                cout << splitted[i] << endl;
            }
            
            
        } //end if
    }
    
    myFile.close();
}

When I test independently the splitting function, it works well, it returns the line stored for each string in a vector.

For instance : split("$ DOUBLE EnergySampler 0.019 $")

returns

(std::vector<std::string>) { "$", "DOUBLE", "EnergySampler", "0.019" }

So far so good ! I just want to pick the "0.019".

But when calling the function inside the test() function there is a problem, the vector I got from using : splitted=split(fichier[i]); appears to have only 2 values whereas you can see above that my line contains 4.

My question then : why the split() works when calling independently and not when call from inside a function ?

Merci d'avance.

PS : I'm compiling my function with ROOT, a C++ interpreter.

1 Answers

Although the code looks pretty OK, I see two bugs on it.

  1. I'm not sure if this is on purpose, but the split function never returns the last match. In your example, calling split("$ DOUBLE EnergySampler 0.019 $") would return the vector ["$", "DOUBLE", "EnergySampler", "0.019"]. Note the missing "$" at the end of the vector. So, to fix this you'd need to check if buf is not empty at the end of the function like below (Also, looks like ROOT interpreter accepts comparing char with string, but I properly defined delim as char in the fix):

    vector<string> split(string myData) {
        vector<string> temporary;
        char delim = ' ';
        string buf= "";
        int i = 0;
        while (i < myData.length()) {
            if (myData[i] != delim)
                buf += myData[i];
            else if (myData[i] == delim) {
                if (buf != ""){temporary.push_back(buf);}
                buf = "";
            }
            i++;
        }
        if (buf != ""){temporary.push_back(buf);}
        return temporary;
    }
    
  2. Second, when you iterate over the splitted vector you're using the i index variable (from the outer for) instead of the k index variable from the inner for. If I fix it like below it works:

            for (int k = 0; k < splitted.size(); k++){
                //number = strtod(splitted[k],&end);
                cout << splitted[k] << endl;
            }
    

So, running it for the benchmark.txt below:

$ DOUBLE EnergySampler 0.019 $
$ DOUBLE Dummy 0.123 $
$ DOUBLE EnergySampler 0.018 $
$ DOUBLE Dummy 0.321 $
$ DOUBLE EnergySampler 0.017 $

It would output the following:

5
$
DOUBLE
EnergySampler
0.019
$
5
$
DOUBLE
EnergySampler
0.018
$
5
$
DOUBLE
EnergySampler
0.017
$
Related