You're almost there, and your program is operating correctly, but not exactly the way you want it to.
A text file (which is what you're dealing with) is treated as a linear stream of bytes (characters) by fgets
. These bytes include not only the "data" bytes (i.e., the '0' and '1' characters you typed as you created the file), but also the newline control character/byte ('\n') which signifies the end of one line and the beginning of the next line.
Each character in the line below represents a linear view of the contents of your file, where each 0 or 1 is the character you typed into the file and \n represents the single-byte newline character stored in the file at the end of each line (i.e., what was placed in the file when you pressed the 'Enter' key on the keyboard to end a line and begin the next line):
The C function fgets
"sees" just a sequence of bytes. The 2nd argument to fgets
represents the size of the buffer into which the bytes read from the stream/file will be placed. fgets
always constructs a valid C string ('\0'-terminated) and fgets
needs to make sure there is room for that string-terminator byte in the buffer it builds. That is why it processes, at most, n-1 characters/bytes from the file at each call.
Your program currently specifies of size of 9 in the call to fgets
. In the first call, fgets
reads the first 8 bytes from the file (the 0's and 1's you typed into the file), places the '\0' string-terminator at the end of that buffer and returns the result to your program.
At the very next call to fgets
, again specifying a buffer size of 9, the file position maintained internally by fgets
is positioned at the newline character ('\n') in the file following the characters/bytes that were previously read. fgets
retrieves the '\n' character, places it into the buffer provided in the call, adds a '\0' as the next character in that buffer (to create a valid '\0'-terminated string) and returns the result to your program. What the program "sees" at that point is a valid C string containing the single newline character ('\n'). That explains the double-spaced output, and also uncovers a few bugs in the readbi()
function: What happens if readbi()
is passed a string containing bytes/characters other than '0' or '1', or the string contains too few bytes (i.e., not exactly 8)?
The above pattern repeats, explaining the seemingly strange output you are seeing.
In a simple case such as this, it is probably easiest to simply declare a buffer larger than any line you expect to process from the file (i.e., 15 bytes), and let fgets
automatically "terminate" each call at each newline character ('\n') in the file. In a real-life program, there needs to be much more input validity checking, parsing, etc., but you're learning.
Also remember that fgets does
return the newline character ('\n') as just another byte in the string, so you need to process it appropriately.
You might want to look at the following. I glanced at a few parts and it seems reasonably well-written, along with many useful pictures. The first link is for the Web view of the article and the second link is for the printable view:http://computer.howstuffworks.com/c.htmhttp://computer.howstuffworks.com/c.htm/printable