0

this is my code below. What it does is not the issue. The issue is that once it is run, I put in my input and if its too small it will ask for input again on the second line which appears to have no affect the flow of my program. If I fill the buffer (which I'm assuming 100 or more) then I am not asked for a second prompt.

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

int main()
{
  int ch;
  char x[3];
  char *word, string1[100];
  x[0]='y';

  while(x[0]=='y'||x[0]=='Y')
  {
    fgets(string1, 100, stdin);
    while ( (ch = fgetc(stdin)) != EOF && ch != '\n');
    printf("The string is: %s", string1);

    word = strtok(string1, " ");
    while(word != NULL)
    {
      printf("%s\n", word);
      word = strtok(NULL, " ");
    }

    printf("Run Again?(y/n):");
    fgets(x, 2, stdin);
    while ( (ch = fgetc(stdin)) != EOF && ch != '\n');
  }

  return 0;
}

EDIT: I have replaced,

    fgets(string1, 100, stdin);
    while ( (ch = fgetc(stdin)) != EOF && ch != '\n');

With,

 fgets(string1, 100, stdin);
 if (string1[98] != '\n' && string1[99] == '\0') 
 { 
   while ( (ch = fgetc(stdin)) != EOF && ch != '\n'); 
 }
Andrew Ricci
  • 475
  • 5
  • 21

3 Answers3

0

The answer to your question is right here: man fgets

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.

To know if fgets used the whole buffer, write some non-NUL byte into the end of the buffer. If, after calling fgets, that byte has been overwritten with a NUL, it means the buffer is full. If the character directly before it is not a newline, then there's more input still to be read.

buffer[size - 1] = 'a'; // any character that's not '\0'
fgets(buffer, size, stdin);
if (buffer[size - 1] == '\0' && buffer[size - 2] == '\n') {
    // handle extra input
}

Alternatively, you could just read bytes one at a time using getchar.

Functino
  • 1,939
  • 17
  • 25
  • Man that's a hassle but I'll give it a go. My teacher asks for every bit of detail. If he asks why there’s a second input and I say I don't know. Marks off for sure. Rightfully so of course! – Andrew Ricci Sep 16 '15 at 13:07
  • @AndrewRicci If the last character in the string read by fgets isn't a `\n`, then the line was too large to fit the buffer. The second input would be to consume the input that is left. – Klas Lindbäck Sep 16 '15 at 13:25
  • I want to thank you for your comment, Much appreciated. – Andrew Ricci Sep 16 '15 at 13:34
0

I think you need this:

Note: x must be int if you want to compare it against EOF

int main()
{
  int x;
  char *word, string1[100];

  do
  {
    fgets(string1, 100, stdin);
    printf("The string is: %s", string1);

    word = strtok(string1, " ");
    while(word != NULL)
    {
      printf("%s\n", word);
      word = strtok(NULL, " ");
    }

    printf("Run Again?(y/n):");
    x = fgetc(stdin);
    fgetc(stdin); // absorb `\n`
  }
  while( (x=='y'||x=='Y') && x != EOF) ;

  return 0;
}
Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
0

From the man page:

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.

fgets will place all input, up to 99 chars, into string1. If you input 98 characters and hit enter (creating a 99th \n), then all 100 will be used as the last one is a \0 terminator.

Then you fall into that small while loop which does nothing but consume another line of input. If you input less than the max for your string, then input is halted while that loop waits for a \n.

If you input >98 characters, then the first 99 are saved to your input string, and the remainder along with that final \n are immediately run through that while loop, causing it to exit quickly enough that it may seem to be skipped.

I hope that helps. Unfortunately I can't comment and ask for clarification, so I'll say here that it's a little difficult to tell what exactly you want fixed or made clear.

ctag
  • 574
  • 2
  • 4
  • 15
  • Very good comment. Thank you for helping me understand fgets better. I have fixed this issue by checking string[99] for a null terminator and string[98] for not a next line char. – Andrew Ricci Sep 16 '15 at 13:31