0

I have this code but every time I run it,it only prints 11(the number of words in the array) over and over again when the amount of words is over 10. When the amount of words is under 10, nothing prints. Please help

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

using namespace std;

int main()
{
    string word;
    fstream file;
    int count = 1;

    file.open("file.txt");
    int numOfLines=0;

    while(!file.eof())
    {
        getline(file,word);
        numOfLines++;
    }
    if(numOfLines<10)
    {
            while(!file.eof())
            {
                getline(file,word);
                cout << word << endl;
                count++;
            }
            cout << "The entire file has been displayed";
    }
    else
    {
        for(int i=0; i<10;i++)
        {
            cout << word << endl;
        }
    }

}
  • 2
    `while(!file.eof())` [https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons) – drescherjm Mar 18 '20 at 19:17
  • 2
    You don't need to count the lines first to complete this task. You can instead count while you read. Also remember after you looped through to the end of the file there are no more lines to read unless you reset the stream to the beginning. – drescherjm Mar 18 '20 at 19:19
  • `system("head -n 10 file.txt");` is simpler. – stark Mar 18 '20 at 20:04
  • 1
    After the first `while(!file.eof())`, how much of the file has been read? How much is left for the second `while(!file.eof())` to read before reaching the end of the file and exiting? – user4581301 Mar 18 '20 at 20:09

1 Answers1

2

To read and print the first ten lines in a file:

#include <iostream>
#include <fstream>

int main()
{
    std::string word;
    std::fstream file;

    file.open("file.txt");

    if(!file.is_open())
        return -1;

    int numOfLines = 0;

    while(getline(file, word) && numOfLines < 10){
        std::cout << word << std::endl;     
        numOfLines++;
    }
}

Live sample

Note that I removed using namespace std; it' s not a good practice, more in Why is "using namespace std;" considered bad practice?

anastaciu
  • 20,013
  • 7
  • 23
  • 43
  • just one question here, is it necessary to have `getline(file,word)` inside the while condition? I ask this because the return value is not a bool and it's `istream object`, can't we just keep it inside the loop? – cppiscute Mar 18 '20 at 19:45
  • 1
    @gocjack, yes it is necessary in case there are less than 10 lines in the file, getline() will return null if there is no line to read. – anastaciu Mar 18 '20 at 19:47
  • Ok. I thought we will stop reading the lines, if by chance we fail to read say line 4. I was thinking if we can check the returned stream object inside the loop then in case of failure to read intermediate line, we can just log and continue reading the next line. – cppiscute Mar 18 '20 at 19:51
  • @gocjack, there is normally more than one way to do things, this way I feel it's the cleanest, if there are no more lines, getline returns null, the condition fails and the cycle ends. – anastaciu Mar 18 '20 at 19:55
  • @gocjack "*the return value is not a bool and it's istream object*" - which is perfectly fine, as `istream` implements [`operator bool`](https://en.cppreference.com/w/cpp/io/basic_ios/operator_bool) and [`operator!`](https://en.cppreference.com/w/cpp/io/basic_ios/operator!) so it can be used in boolean contexts for error checks, such as in loop conditions. Personally, in this example, I would use a `for` loop instead of a `while` loop since the number of iterations is known, eg: `for(int numOfLines = 0; getline(file, word) && (numOfLines < 10); ++numOfLines){ std::cout << word << std::endl; }` – Remy Lebeau Mar 18 '20 at 20:01
  • @RemyLebeau thanks, now I understand how and why we use the objects inside the loop conditions. – cppiscute Mar 18 '20 at 20:12