fgets reads characters from the current stream position to and including the first newline character, to the end of the stream, or until the number of characters read is equal to n – 1, whichever comes first.
The first read is the 4 characters and the second is the newline. So you have 2 reads per line.
EDIT: A possible solution is to ignore the newline character.
You are using C to perform the task I have included a heavily commented Cpp version which uses auto pointers which
automatically clears up memory for you. You don't need to use malloc and such. This program uses exceptions to detect a change
in the file stream when EOF(end of file) is reached. I use this to prevent the printing of the extra line number when eof is reached.
#include <iostream> // c++ i/o
#include <fstream> // file i/o
#include <memory> // auto pointers
#include <exception> // exceptions
#include <cstdlib> // exit function
using namespace std;
// Using the linux GNU g++ compiler
int main(int argc, char *argv[])
{
ifstream fin; // create file input stream 'fin'
fin.exceptions(ios::failbit | ios::badbit); // set exceptions for i/o errors
try { // use exceptions try block to test for a filename entered
if (argc != 2) throw exception();
} catch (const exception& e) {
cerr << "\n\tInput Error: You must enter a Filename" << endl;
exit (1);
}
// create auto ptr string from filename entered at command line
const auto_ptr < string > FileName (new string (argv[argc - 1]));
auto_ptr <string> Result (new string); // create another auto ptr string called Result
try {
fin.open(FileName->c_str(),std::ios_base::in); // open file for reading
// as data is an auto ptr we have to use ->c_str() to append the asciiz terminator
// to the string and not the '.c_str()' that an ordinary string would use.
} catch( ios_base::failure ex) {
cerr << "\n\tError: Unable to open " << *FileName << endl;
exit (1);
}
int LineNumber = 0;
do {
try {
getline(fin,*Result);
LineNumber++;
} catch( ios_base::failure ex) { // we use an exception to clear & close the stream once we reach EOF
fin.clear(); // If we rely on fin.eof() to close it. It will give another pass through
fin.close(); // to do-while loop printing a "4" after the line "3: ghi"
return 0;
}