Search code examples
cfile-handlingfgetc

why does only the 1st file reading function executes over multiple programs of the same kind in C language?


This code contains 3 file handling related functions which read from a file named "mno". But only the 1st called function in the main() is working. If the 1st function of the list is commented then, only the 2nd function will work and the third won't. Same goes for the 3rd one

#include <stdio.h>
#include <ctype.h>
#include <unistd.h>

void countVowel(char fin[])
{
  FILE *fl;
  char ch;
  int count = 0;
  fl = fopen(fin, "r");
  while (ch != EOF)
  {
    ch = tolower(fgetc(fl));
    count += (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') ? 1 : 0;
  }
  fclose(fl);
  printf("Number of Vowels in the file \" %s \"-> \t %d \n", fin, count);
}

void countConsonant(char fin[])
{
  FILE *fl;
  char ch;
  int count = 0;
  fl = fopen(fin, "r");
  while (ch != EOF)
  {
    ch = tolower(fgetc(fl));
    count += (!(ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') && (ch >= 'a' && ch <= 'z')) ? 1 : 0;
  }
  fclose(fl);
  printf("Number of Consonant in the file \" %s \"-> \t %d \n", fin, count);
}

void countAlphabet(char fin[])
{
  FILE *fl;
  char ch;
  int count = 0;
  fl = fopen(fin, "r");
  while (ch != EOF)
  {
    ch = tolower(fgetc(fl));
    count += (ch >= 'a' && ch <= 'z') ? 1 : 0;
  }
  fclose(fl);
  printf("Number of Alphabets in the file \" %s \"-> \t %d \n", fin, count);
}

int main()
{
  countVowel("mno"); // output -> 10
  countConsonant("mno"); // output -> 0
  countAlphabet("mno"); // output -> 0
  return 0;
}

Here are the contents of "mno" file ->

qwertyuiopasdfghjklzxcvbnm, QWERTYUIOPASDFGHJKLZXCVBNM, 1234567890

Solution

  • You are using ch uninitialized. at while (ch != EOF). Every function call after the first has ch equal to 0 at the start, because you forgot to initialize it and the memory was set to -1 before. You can fix it by replacing the loops like this:

    int ch;
    ...
    while ((ch = fgetc(fl)) != EOF)
    {
        ch = tolower(ch);
        count += ...;
    }
    

    Here ch is getting initialized before you check it and later converted to lowercase.

    EDIT:

    Note that this only works if ch is an int, so it can handle the value of -1 (EOF) and the byte 255 is not truncated to -1.

    EDIT:

    At first I said ch was 0 all the time. It was -1. I am so sorry, I swapped it with the null terminator, which is usually the reason for such behavior.