-1

I apologize in advance because I just started learning C. This is my code so far.

int main ()
{
char buf [4];
// open the file
FILE *fp = fopen("readme","r");

// Return if could not open file
if (fp == NULL)
    return 0;

while(fgets(buf,4,fp) != NULL){

    // Checking for end of file
    if (feof(fp))
        break ;

    fputs(buf,stdout);
}  while(1);

fclose(fp);
return(0);
}

Im having trouble getting the results I need. I assume that setting a buffer to 4 would likely return the first four characters of each line. I could be wrong but Ive been stuck on this a few hours trying to figure out how to Overflow the Buffer. Appreciate any help, Thanks!

  • The file is being read correctly and properly printed I just feel like the "fgets" or misunderstanding of the buffer is where im messing up. – Eric Rawls Feb 23 '18 at 20:08
  • 1
    What is your question? What is this program supposed to do, what is it doing instead? – Barmar Feb 23 '18 at 20:10
  • If the line (including the newline character) is longer than 3 , then `fgets` will only read 3 bytes. The next `fgets` will read again up to 3 bytes and so on. – Pablo Feb 23 '18 at 20:11
  • 1
    ` while(1);`. This is an infinite loop. You don't need this. – H.S. Feb 23 '18 at 20:14
  • Please read the man page for `feof`. It is different from the same-name function in, say, PHP. In C it tells you if an attempt was made to read past the end of a file, so it is an error condition. In PHP it tells when you reached end of file. In C your loop control `while(fgets(buf,4,fp) != NULL)` will not try to read from past the end of the file, so `feof` is of no use here. – Weather Vane Feb 23 '18 at 20:19
  • `char buf [4];` can only hold **3** characters because `fgets` always supplies the C "string" nul terminator. Your hope that the code will show the first 4 characters of each line is also false, because when the buffer limit is reached, the rest of the line is not skipped, but the next 4 (actually 3) characters will be read by the next `fgets`. – Weather Vane Feb 23 '18 at 20:22
  • @Barmar This is the assignment I was given. Its very vague but im trying to understand what occurs when a buffer is shorter than the given input. – Eric Rawls Feb 23 '18 at 20:24
  • @barmar - "type in the program that copies a file using line-at-a-time I/O (fgets and fputs) from Figure 5.5 (fgets.cpp) but use a MAXLINE of 4. What happens if you copy lines that exceed this length? Explain what is happening" – Eric Rawls Feb 23 '18 at 20:24
  • @weathervane so why is it return my file entirely? thats my big question. Wouldn't my strings be cut short or what not? – Eric Rawls Feb 23 '18 at 20:25
  • See the good answer, and please read the man page for functions before asking. They were written: for **you**. – Weather Vane Feb 23 '18 at 20:26
  • @EricRawls You should put that in the question (and not just the title). And the question needs to explain what you think is going wrong. – Barmar Feb 23 '18 at 20:31
  • Why do you want to overflow the buffer? If you want to do that, just set the `size` argument to `fgets()` larger than the size of `buf`. – Barmar Feb 23 '18 at 20:32

1 Answers1

2

You are not understanding how fgets works.

fgets will read up to 3 characters (and not 4, because fgets '\0'-terminates the buffer). If the newline '\n' is among these 3, fgets will stop reading and writes the newline and returns, otherwise it continues until the buffer is full.

Let's say the input is: This is a very long line\nThis is another line\n, then fgets will read the first 3 characters and store 'T', 'h', 'i', '\0 in the buffer. The next time fgets reads the next 3 characters: 's', ' ', 'i' and store them in the buffer. Eventually it will reach to the first newline, and stops reading there.

In general fgets will try to read the max number of characters that the buffer can hold. If the newline is among these characters, it stops reading and writes the newline in the buffer as well. If the newline is not found among them, then fgets will stop when the buffer is full.

Whether fgets reads a whole line depends on the size of the buffer, so even with two consecutive calls of fgets, you might not still getting the whole line, as I showed you with the example above. That's why your assumption I assume that setting a buffer to 4 would likely return the first four characters of each line is wrong.

The only way to know if fgets read a whole line is looking whether the newline was written in the buffer.

Also note that

if (feof(fp))
    break ;

is not needed here, because fgets will return NULL when the end-of-file is reached and no more characters can be read, the loop will end anyway, so doing the extra check is pointeless.

And this

while(fgets(buf,4,fp) != NULL){
    ...
} while(1);

is the same as this:

while(fgets(buf,4,fp) != NULL){
    ...
}

while(1);

So after reading the whole file, you are entering in an endless loop.

Pablo
  • 13,271
  • 4
  • 39
  • 59
  • Wow thanks very much! You cleared up a few things I wasn't sure about. – Eric Rawls Feb 23 '18 at 20:33
  • I suspect the extra `while(1)` is because he started with a `do-while` loop with `feof()` check and `break`, changed it to a `while` loop, but forgot to remove the `feof()` and second `while`. – Barmar Feb 23 '18 at 20:33
  • @Barmar that was my guess too. – Pablo Feb 23 '18 at 20:34