Search code examples
cmallocfgets

Anomalous behaviours of fgets()


Input Format

The first line contains two integers, N and M, separated by a single space, where N represents the number of people, and M represents the number of topics. N lines follow. Each line contains a binary string of length M. If the ith line's jth character is 1, then the ith person knows the jth topic; otherwise, he doesn't know the topic.

Constraints

2≤N≤500 1≤M≤500

Code

int main() 
{
    int i,j,k,m,n;
    char *str='\0';
    //n - no of persons
    //m - no of topics

    //Read the m and n from console
    scanf("%d %d\n",&n,&m);

    //Allocate the memory
    str=malloc(501);


    for(i=0;i<n;i++)
    {
        fflush(stdin);
        if(fgets(str,501,stdin)!=NULL)
        {
            if(strlen(str)>0 && str[strlen(str)-1]=='\n')
                str[strlen(str)-1]='\0';
        }
        printf("%s\n",str);
    }


    //Free used variables
    free(str);

    return 0;

}

Sample Input 1 -

4 5
10101
11100
11010
00101

Sample Output 1 -

10101
11100
11010
00101

Result : Expected output matches the printed output.

Sample Input 2 -

4 500 
11100110111100111011001010001110110100111111100111110111100111000110110011111111001001010111111111011011110000111001101011110101011100111011001011110100011011001110110111110010111010100001111011111110110111010101101001111100010111011110011111100110011101110111100110010110111111011010110110011101001011110101110100110011010101111011101111010100011101110110101110101101010110101010111111111001100001110100011010110101110110111111111111111001100101110111110110011010011101110100010111110000000110110110    
10101010101001110011110110011101111001011001110101011101111110101011011110010100110011110111111010100001111111111010101111110110111101110101111111100010011011101010111011111010111001111110101110111011100010110101001001001101110111110111011111111101110010100110110011111100101010100001111111111010011001111101010011111110111011001001110111010111111111011011010011101101000010101010011110100111111110101011110011110001110111111011101100011100101100101111111110011101001110101011111001111100111110010001    
11111101101110110110111101101111111111110001110100111001010111011011011111011111111010010101111011000101001101110100111111111001110111111101000011110100010001010111101010111111111010111011011110000111010111101011110111100110010000001111111101101110110010010111010111100010100000010011111001100101101011101111000101110110011111110110111111111011010011001000111101101001011101011010010111100001111011001111111001110110011011111011101001001011001111111001011111011111010111010011111010100110110111111100    
11111000011111101111111101001100011011111110011110110111011111111100110100011100011111011111011111001010010110110111111000100110111101111000111101100001110000101010011001101101100011000001111010001111101011000110001111110100101001011011111010001101101110011110101001011100111100011111011110001110100100111111111110100110111011101111000011001101111000101011111001101010111100110011101100100010011111111111011110011100011111111011011110011011101110111110011111011111111101111011110111001111010001111001

Sample Output - 2

11100110111100111011001010001110110100111111100111110111100111000110110011111111001001010111111111011011110000111001101011110101011100111011001011110100011011001110110111110010111010100001111011111110110111010101101001111100010111011110011111100110011101110111100110010110111111011010110110011101001011110101110100110011010101111011101111010100011101110110101110101101010110101010111111111001100001110100011010110101110110111111111111111001100101110111110110011010011101110100010111110000000110110110
10101010101001110011110110011101111001011001110101011101111110101011011110010100110011110111111010100001111111111010101111110110111101110101111111100010011011101010111011111010111001111110101110111011100010110101001001001101110111110111011111111101110010100110110011111100101010100001111111111010011001111101010011111110111011001001110111010111111111011011010011101101000010101010011110100111111110101011110011110001110111111011101100011100101100101111111110011101001110101011111001111100111110010001

Expected Output 2 - It should contain 4 lines of text instead of 2 in the output.


Solution

    1. Remove '\n' from scanf("%d %d\n",&n,&m);. The '\n' complicates input. Any whitespace as a scanf() directive like '\n', ' ', '\t', etc. matches any number of white-space. So scanf() will not return until non-white-space is entered after the 2 numbers.

    2. Do not mix scanf() with fgets(). Instead use fgets() and qualify inputs:

      char buf[50];
      fgets(buf, sizeof buf, stdin);  // Should also check `fgets() results
      if (2 != sscanf(buf,  "%d%d", &n, &m) || n < 2 || n > 500 || [more tests]) {
        puts("Bad input");
        return 1;
      }
      
    3. Remove fflush(stdin);.

    4. Put printf("%s\n",str); inside the preceding if(fgets... block.

    5. Allocate 502, not 501. +1 for the '\n' and +1 for the '\0'. This is why your last test case is failing. Code is trying to read a line with 500 char and a '\n' which is 501 char. The 501 passed to fgets() inidates room for 500 char and a terminating null character '\0'.

    6. char *str='\0'; is strange. Suggest char *str = NULL;

    7. Suggested for loop

      str = malloc(502);
      for(i=0;i<n;i++) {
        if(fgets(str,502,stdin)!=NULL) {
          if (strlen(str)>0 && str[strlen(str)-1] == '\n')
            str[strlen(str)-1] = '\0';
          }
          printf("%s\n",str);
        }