-1

I'm developing a code where the user will type several paragraphs and it will stop reading when the user begin a paragraph with "END". The code will manipulate the string by counting each letter and showing a graph and blah blah blah, but this is irrelevant to the question. The thing is: which paragraph must have no more than 1000 characters.

A smaller version of the code is the following (considering I just want to storage 5-char-string - even though I'll expand that).

#include <stdio.h>
#include <string.h>

int main()
{
  char paragraph[5];

  for ( ; ; )
  {
    fgets(paragraph, 5, stdin);

    if (paragraph[0]=='E' && paragraph[1]=='N' && paragraph[2]=='D')
    { return 0; }

    printf("%s", paragraph);
  }

  return 0;

My problem is: if I type more than 5 characters, the printf function still prints more than 5 characters, I don't know why. I've already checked everything I could possible check.

Help a beginner like me, please.

Shofukan
  • 57
  • 7
  • 2
    Your `printf` doesn't print a newline or similar, so you'll read five characters, print them, and read another five and print them straight after. You're reading 5 at once, it's just you're doing it multiple times. Try printing a character before `%s` to verify if this is the case. – slugonamission May 29 '16 at 17:30
  • 2
    *"I've already checked everything I could possible check."* - except the return value from `fgets`. – Weather Vane May 29 '16 at 17:37
  • It types more than 5 characters because `fgets` does not discard the rest of the line: it reads *all* the input. – Weather Vane May 29 '16 at 17:40
  • I've already check, WITHIN MY KNOWLEDGE* – Shofukan May 29 '16 at 17:41

3 Answers3

1

fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer. A terminating null byte ('\0') is stored after the last character in the buffer.

So when entering more than 4 characters (newline included) only 4 is read and the rest stays in the buffer ready to be read next fgets.

Your printf will not print any newline in this case and will be called multiple times, making it look like printing more than 4 characters.

As suggested in comments, try printf("[%s]", paragraph); to see the individual printf calls.

totoro
  • 2,469
  • 2
  • 19
  • 23
  • Yeah, I tried printing "%s\n" and now I see it. But now I don't know two things: (1) how to get rid of the remaining characters I don't want and (2) how can I possible print more than 5 chars if my array has only 5 positions. Jesus... maybe coding is not for everyone or I'm stupid. – Shofukan May 29 '16 at 18:18
  • 1) See http://c-faq.com/stdio/stdinflush2.html. 2) print multiple times or increase your array size and read into next position in the array. Hope it helps, keep trucking. – totoro May 29 '16 at 18:47
0

Try modifying your code in the following way and you'll immediately see what actually happens with the fgets() function when you enter more characters than the size of your buffer. It doesn't read from the keyboard, but from the stdinbuffer. These SO posts may also be interesting for you to read:(1), (2). Enjoy the demo and be sure to thoroughly read the man pages.

#include <stdio.h>

int main()
{
  char paragraph[5];

  for ( ; ; )
  {
    printf("Enter the string: \n\t");

    if(fgets(paragraph, 5, stdin) != NULL)
        printf("%s\n", paragraph);

    if (paragraph[0]=='E' && paragraph[1]=='N' && paragraph[2]=='D')
        return 0;    
  }
  return 0;
}
Community
  • 1
  • 1
user3078414
  • 1,942
  • 2
  • 16
  • 24
  • But how can I print only the 5 chars? It seems so easy, but I just can't do it. By the way, where are the chars storaged? How can the printf function print more than 5 chars if my array only has 5 positions? – Shofukan May 29 '16 at 18:40
  • Please, run this demo and you'll **_immediately_** see where's the problem in your code. Also, take a look at the answer by @Nightcrawler. – user3078414 May 29 '16 at 18:42
0

You should use strstr in string.h because it's cleaner.

if (strstr(paragraph, "END"))
 return 0;

instead of

if (paragraph[0]=='E' && paragraph[1]=='N' && paragraph[2]=='D')
 return 0;  
potheo
  • 17
  • 1
  • 5