Search code examples
c++stringfilefstreamgetline

Why is my string empty when taking input from file?


I have a huge file full of numbers (2 billion). So this is a file splitter that splits my file in groups of 100000 numbers. but this is returning empty files full of spaces and enters. I even tried to change the data type of the variable. I am struck. please suggest.

    #include <iostream>
    #include <vector>
    #include <string>
    #include <iterator>
    #include <fstream>
    #include <algorithm>
    using namespace std;
    int main()
    {
        std::ifstream ifs("prime.txt");

        unsigned long long int curr;
        unsigned long long int x = 0;
        string li;
        int count;
        while (getline(ifs, li))
        {
            count ++;
        }
        ifs.seekg(ios::beg);
        string v;
        while (curr < count)
        {
            x++;
            std::string file = to_string(x) ;
            std::string filename = "splitted\\"+file+ ".txt";
            std::ofstream ofile (filename.c_str());

            while (curr < 100000*x )
            {

                ifs >> v ;
                ofile << v << "\n";
                curr++;
            }
            ofile.close();
        }

    }

Solution

  • You have 2 uninitialised variables, count and curr, your compiler should have warned you about these. If it didn't make sure you have enabled compiler warnings.

    After the last getline in your initial while loop fails the stream will have the fail and eof flags set. Due to the stream not being in the good state all further operations on it will fail so your seekg will be ignored as will all your reads. To fix this call ifs.clear(); before your seekg.

    As you don't seem to need the line count anywhere pre-calculating it is unnecessary and as you are then not reading the file in lines it will lead to incorrect behaviour if your file has more than one value on a line. Your code can be simplified to:

    #include <iostream>
    #include <vector>
    #include <string>
    #include <iterator>
    #include <fstream>
    #include <algorithm>
    using namespace std;
    int main()
    {
        std::ifstream ifs("prime.txt");
        if (!ifs)
        {
            std::cout << "error opening input file\n";
            return 1;
        }
    
        int64_t fileNumber = 0;
        int64_t fileCount = 0;
        std::ofstream ofile;
        while (ifs)
        {
            if (!ofile.is_open() || (fileCount >= 100000))
            {
                ofile.close();
                fileCount = 0;
                fileNumber++;
                std::string file = to_string(fileNumber);
                std::string filename = "splitted\\" + file + ".txt";
                ofile.open(filename.c_str());
                if (!ofile)
                {
                    std::cout << "error opening output file\n";
                    return 1;
                }
            }
            std::string value;
            if (ifs >> value) {
                ofile << value << "\n";
                fileCount++;
            }
        }
    }