Strange incrementing problem

Hi,
The main aim is to read a file and output its content.
The content of file is
abc
def
ghi

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int main()
{
        int i=0;
        FILE *fp;
        fp = fopen("data","r");
        char* str;
        str = (char *)malloc(4*sizeof(char));
        while(!feof(fp))
        {
                fgets(str,4,fp);
                printf("%d %s",i,str);
                i++;
                bzero(str,4);
        }
        fclose(fp);
        return 0;
}


Ideally, the code should output
0 abc
1 def
2 ghi

But, the above code ouputs
0 abc1
2 def3
4 ghi5
6

I don't understand how come the variable 'i' is getting incremented twice for each iteration?

Thank you.
I don't understand how come the variable 'i' is getting incremented twice for each iteration?
No it isn't. If you look at this
0 abc1
you see 0 and 1. That is because you read empty string (with zero length)
I am sorry but I don't understand your point.
The loop runs thrice, isn't it ?

How and why is it reading an empty string for the above input?
What is the possible solution to get an output like this then?
0 abc
1 def
2 ghi

Thanks for your reply.
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.
Last edited on
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;
}

std::cout << LineNumber << ": " << *Result << std::endl; // display result

} while (!fin.eof()); // end of do-while loop
fin.clear(); // restore stream status
fin.close(); // before leaving





return 0;
}
Topic archived. No new replies allowed.