-2

Here is the code:

void makefiles(char* filename) {
    ifstream file(filename, ios::in);

    // number of entries in main file 
    int size = 0;

    // names is the vector that holds entries 
    vector<string> names;
    string tmpstr;

    while (getline(file, tmpstr)) {
        string toadd = "";
        for (int i = 0; i < tmpstr.size(); i++) {
            if (tmpstr[i] != '|')
                toadd += tmpstr[i];
            else
                break;
        }
        if(count(names.begin(), names.end(), toadd) == 0)
            names.push_back(toadd);
        size++;
    }
    file.close();

    ofstream userfile;
    file.open(filename, ios::in);
    for (int i = 0; i < names.size(); i++) {
        userfile.open(string(getenv("TEMP")) + "\\" + names[i] + ".txt", ios::out);
        
        cout << string(getenv("TEMP")) + "\\" + names[i] + ".txt" << endl;
        
        while (getline(file, tmpstr)) {
            if (tmpstr.rfind(names[i], 0) == 0) {
                userfile << tmpstr << endl;
                userfile.flush();
            }
        }
        userfile.close();
    }

    file.close();


}

This function is being called from main, filename contains some formatted text, like email database of the next view:

gottaletitout@gmail.com|timetogo@gmail.com|06.01.2023|21:09:30|born in the abyss|156
gottaletitout@gmail.com|timetogo@gmail.com|06.01.2023|21:09:30|born in the abyss|156
a@gmail.com|b@gmail.com|23.12.2009|13:52:16|prikol|13
hottaletitout@gmail.com|timetogo@gmail.com|06.01.2023|21:09:30|aorn in the abyss|156

Thus, one line is one entry

In conclusion, I get many empty files that have the names i want, but, again, they are empty

I tried adding right after opening userfile:

if(!userfile){
    cout << "File is not opened" << endl;
    return;
}

But it doesn't help because !userfile = false

I tried instead of userfile << tmpstr << endl, using userfile << tmpstr << flush;

Alan Birtles
  • 32,622
  • 4
  • 31
  • 60
  • Can you please create a [Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example)? – madhur4127 Jan 08 '23 at 14:48
  • 1
    The writing of the output file (after opening) is in a loop, and subject to a number of conditions. Try checking if the loop iterates at all (if it doesn't, no output will be produced) and if the various `tmpstr.rfind()` calls are producing a zero value. Also, what do you expect to happen on iterations of the loop after the first - the first iteration will read to the end of `file`, and subsequent iterations will read starting at the end of the file. – Peter Jan 08 '23 at 14:51
  • Please provide enough code so others can better understand or reproduce the problem. – Community Jan 08 '23 at 14:51
  • code is incomprehensible - at the very least check that the files opened – Neil Butterworth Jan 08 '23 at 14:53
  • @madhur4127 i'm calling this function like: ``` int main(int argc, char* argv){ makefiles(argv[1]); } ``` The filename (the "database") is passed to program as comand line argument – JosephWilliamsen Jan 08 '23 at 14:53
  • sounds like the first call to `getline(file, tmpstr)` is failing so nothing is ever written to the file – Alan Birtles Jan 08 '23 at 14:54
  • You are only writing one file. On the first iteration of the last `for` loop, with `i==0`, the inner `while` loop reads `file` all the way to EOF. On all subsequent iterations, `file` is already at EOF and all `getline` calls fail immediately. So all the files but the first (named after `names[0]`) are created but never written to. – Igor Tandetnik Jan 08 '23 at 14:56
  • There should be no need for closing or flusing files. streams are RAII objects and should take care of that for you. Also you could leave all the error handling to exception handling `ofstream.exceptions ( ifstream::badbit );` and get some extra information from the exception `what()`. – Pepijn Kramer Jan 08 '23 at 14:57
  • @JosephWilliamsen you're doing too many things in that function. You're first skimming to get the names and then reading again with simultaneous writes. Too much scope to debug. You should [use a debugger](https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems) and find the actual problematic code. Of course this comment doesn't help you immediately but shows you path to resolve such issues yourself and ask concise question benefitting everyone. – madhur4127 Jan 08 '23 at 14:58
  • Note that in `ifstream file(filename, ios::in);` the `, ios::in` is redundant. That's what the initial `i` stands for. – Pete Becker Jan 08 '23 at 16:02

1 Answers1

1

You are writing at most one file. On the first iteration of the last for loop, with i==0, the inner while loop reads file all the way to EOF. On all subsequent iterations, file is already at EOF and all getline calls fail immediately. So all the files but the first (the one named after names[0]) are created but never written to.

Igor Tandetnik
  • 50,461
  • 4
  • 56
  • 85
  • Yeah, after you mentioned it, i added ```file.clear(); file.seekg(0, ios::beg);``` at the end of iteration, and everything is working now thanks – JosephWilliamsen Jan 08 '23 at 15:02