1

I have written the below code to sort strings in alphabetical order.But I m unable to understand how fgets is working here.

#include<stdio.h>
#include<string.h>
int main()
{
    char s[10][15];
    int n;
    printf("enter the no of names\n");
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
       fgets(s[i],15,stdin);
       //scanf("%s",s[i]);
    }
    for(int i=1;i<n;i++)
    {
        for(int j=0;j<n-i;j++)
            if(strcmp(s[j],s[j+1])>0)
        {
            char g[15];
            strcpy(g,s[j]);
            strcpy(s[j],s[j+1]);
            strcpy(s[j+1],g);
        }
    }
    printf("the sorted strings are");
    for(int i=0;i<n;i++)
        printf("%s",s[i]);
    return 0;
}

If I use scanf instead of fgets to accept strings, n words are accepted but when I'm using fgets for same purpose instead of scanf, n-1 words are accepted. Why is it so?

Is fgets placing last newline character in the nth place?

dbush
  • 205,898
  • 23
  • 218
  • 273
  • What length are the strings you are entering? Does it make a difference if you replace `15` with `100` everywhere? Is there an "empty" string in a redirected file (`scanf` ignores whitespace)? Also please see [Removing trailing newline character from fgets() input](https://stackoverflow.com/questions/2693776/removing-trailing-newline-character-from-fgets-input/28462221#28462221) – Weather Vane Aug 17 '18 at 18:37
  • @WeatherVane I m not entering more than 14 characters and how does that matter here? – Mubashira khanum Aug 17 '18 at 18:39
  • Just make the string lengths 100 and remove all doubt. `fgets` retains the newline, perhaps you are not counting the extra **two** elements needed for newline and nul terminator. @dbush answer is good, but your string lengths are still too short for 14 chacacters. – Weather Vane Aug 17 '18 at 18:40
  • The `scanf()` leaves an "empty" `\n` in the buffer. That "empty" `\n` gets read in the first `fgets()` call. Don't mix `scanf()` and `fgets()`. – pmg Aug 17 '18 at 18:41
  • @WeatherVane Only null terminator gets added right?Because newline stays in buffer. – Mubashira khanum Aug 17 '18 at 18:42
  • Nope, `fgets` reads the newline. Please don't be mean with buffer sizes. – Weather Vane Aug 17 '18 at 18:42
  • 1
    As an aside, why are you prompting for the number of inputs? Read the data one line at a time until there's no more data. Doing so is more idiomatic and less error prone. – William Pursell Aug 17 '18 at 18:45

1 Answers1

3

This is what happens when you mix fgets and scanf calls in the same program.

You start out using scanf to read the number of names. This reads a number and leaves a newline in the input buffer. When you then go into your loop and call fgets for the first time it reads that newline in the buffer immediately and then goes to the next iteration of the loop, calling fgets again.

When you use scanf in the loop instead, the %s format specifier first reads and discards and whitespace characters, which includes the newline from the prior scanf call.

If you still want to use fgets, you first need to clear the input buffer prior to the loop by calling getchar until you read a newline. Also, keep in mind that fgets includes the newline in the string it reads.

dbush
  • 205,898
  • 23
  • 218
  • 273