Search code examples
c++fstreamfile-handlingifstreamofstream

How to load data into a vector from a text file that has been created inside the same program. in C++


I want to load data from a Text file that has been created in the same program into a vector of strings. But no line of text is getting pushed into the vector here.

Here First I am reading data from some input file and then doing some operations (Removing extra spaces) on it then I save this file as "intermediate.txt". This intermediate.txt is being created and all the operations that I want to do happen successfully. Finally, I want to read this file into a vector<string> code but it doesn't work. I can't store anything in the vector<string> code. Its size is Zero.

#include <bits/stdc++.h>
using namespace std;

int main()
{
    string inputFileName;
    cout << "Enter the Input File Name: ";
    cin >> inputFileName;
    ifstream f1(inputFileName);
    ofstream f0("intermediate.txt");
    string text_line;

    while (getline(f1, text_line))
    {
        string word;
        istringstream text_stream(text_line);
        while (text_stream >> word)
        {
            f0 << word << " ";
        }
        f0 << "\n";
    }
    f0.close()
    ifstream file("intermediate.txt");
    vector<string> code;
    string line;
    while (getline(file, line, '\n'))
    {
        code.push_back(line);
    }

    for (auto it : code)
    {
        cout << it << "\n";
    }
}

Solution

  • Here's a mini-code review:

    #include <bits/stdc++.h>  // Don't do this; doesn't even compile for me
    using namespace std;      // Don't do this either
    
    int main()
    {
        string inputFileName;
        cout << "Enter the Input File Name: ";
        cin >> inputFileName;
        ifstream f1(inputFileName);  // Bad name
        ofstream f0("intermediate.txt");  // Bad name
    
        // You never check that you successfully opened *any* files.
    
        string text_line;
    
        /*
         * You don't describe why this is necessary, can a line not be read and
         * written as-is? Is it already a line of space-separated variables?
         *
         * In any case, this is where you already have the words; so store them in
         * the vector here as well.
         */
        while (getline(f1, text_line))
        {
            string word;
            istringstream text_stream(text_line);
            while (text_stream >> word)
            {
                f0 << word << " ";
            }
            f0 << "\n";
        }
        f0.close()  // Forgot your semi-colon
                    // Left f1 open, that's bad practice
        ifstream file("intermediate.txt");
        vector<string> code;
        string line;
    
        /*
         * I would hope you felt that reading from a file, writing to a new file,
         * closing both files, opening the new file, and reading from the new file
         * into the vector was wasteful.
         */
        while (getline(file, line, '\n'))
        {
            code.push_back(line);
        }
    
        for (auto it : code)
        {
            cout << it << "\n";
        }
    }
    

    The most immediate issue with your original question was that you tried to open the same file in two different streams. The second time, the file failed to open, but because you never check if you actually opened the file, you assumed everything worked fine, but it didn't, which brought you here.

    However, there is a better way.

    #include <fstream>
    #include <iostream>
    #include <sstream>
    #include <string>
    #include <vector>
    
    int main() {
      std::string inputFileName;
      std::cout << "Enter the Input File Name: ";
      std::cin >> inputFileName;
    
      // Always check that you successuflly opened the file.
      std::ifstream fin(inputFileName);
      if (!fin) {
        std::cerr << "Error opening: " << inputFileName << ". Exiting...\n";
        return 1;
      }
    
      std::ofstream fout("intermediate.txt");
      if (!fout) {
        std::cerr << "Error opening: intermediate.txt. Exiting...\n";
        return 2;
      }
    
      std::vector<std::string> code;
    
      std::string text_line;
      while (std::getline(fin, text_line))  // You've read the line
      {
        std::string word;
        std::istringstream text_stream(text_line);
        while (text_stream >> word) {
          fout << word << " ";
        }
        fout << "\n";
        code.push_back(text_line);  // Just store it while you have it
      }
      fin.close();   // Best practice is to close a file as soon as you're done
      fout.close();  // with it. Don't hog resources.
    
      for (const auto& it : code)  // Avoid making copies
      {
        std::cout << it << "\n";
      }
    }
    

    The while loop, where you read the lines that you want to store in the vector, now writes to your file and stores the lines into the vector. We also now check whether we successfully opened files, and we close the file streams as soon as we're done with the file so as to not keep it locked for no good reason.

    A good next step for improving this program a bit more would be to avoid asking the user for a file name. Instead, take it as an argument to main(). That way, someone only has to type ./a.out input.txt on the command line and the program will do the job automatically.