-2

I am a beginner in programming and I am learning C . I tried to read the contents from a file and do some processing on it .

The following is the program that I had written :

#include <stdio.h>

int main()
{
    FILE *fp ;
    int k = 0 ;

    char c ;
    while (c = getc(stdin))
    {
        if (c == 'a')
        { 
            ++k;
        }
    }

    printf ("the value of k is %i" , &k) ;
}

And the file had input :

 > hkjkjaaaaaaaaaak
 > 
 > hjkjlkaaaaaaaaaghgh
 > 
 > hjhkjklklklklklk

But I did not get any output in the console . I ran it on another online IDE and I got a run-time error saying "Time limit exceeded"

What can be the reason for the absence of output . Is it because I needed to somehow specify EOF character in the absence of which the program keeps running on and on?

After getting help from the answers I replaced the code with the following :

#include <stdio.h>

int main()
{
    FILE *fp ;
    int k = 0 ;

    char c ;
    while (c  = getc(stdin) != EOF)
    {
        if (c == 'a')
        { 
            ++k;
        }
   }


   printf ("the value of k is %i" , k) ;
}

This time the program ran and I got an output saying :

the value of k is 0.

Did it somehow reach EOF from the very beginning ?To verify this I tried comparing the character with 'h' and got the same output .

Is it because getc returns integer and this is not matching with any of the characters in the text ?

Thanks a lot for all the insights . The code worked at the end .Cheers

  • 1
    `FILE *fp` does not open any file. It simply declares a pointer to a file object – Fureeish Nov 18 '17 at 15:33
  • When does `c = getc(stdin)` become false? Need to change this condition to take into account EOF – Ed Heal Nov 18 '17 at 15:35
  • 3
    There are *multiple* problem with the code you show. To begin with [`getc`](http://en.cppreference.com/w/c/io/getc) return an ***`int`***. This is very important. It also *doesn't* return zero for end-of-input. Then `&k` gives you a *pointer* to `k`. I recommend you *start over* [with a couple of good beginners books](http://stackoverflow.com/questions/562303/the-definitive-c-book-guide-and-list). – Some programmer dude Nov 18 '17 at 15:35
  • `getc` returns the read `char` as an `unsigned char` cast to an `int`, or `EOF` on end of file or error, and not `0`. Your loop will never break unless you have a break condition. – brokenfoot Nov 18 '17 at 15:38
  • 1
    `char c`->`int c`, `while ...` -> `while ((ch = getc(stdin)) != EOF)` – Ed Heal Nov 18 '17 at 15:40
  • `c = getc(stdin) != EOF` (your code) and `(ch = getc(stdin)) != EOF` (the correct suggestion) are not the same, due to [operator precedence](http://en.cppreference.com/w/c/language/operator_precedence) – UnholySheep Nov 18 '17 at 16:09
  • @UnholySheep : Nice insight . – Kanishk Viman Nov 18 '17 at 16:15

1 Answers1

1

Your compiler should have warned you about this:

while (c = getc(stdin) != EOF)

warning: using the result of an assignment as a condition without parentheses [-Wparentheses]

Because != (inequality) has a higher priority over = (assignment), the line is interpreted as

while (c = (getc(stdin) != EOF))
           ^                  ^

Note the unexpected parentheses, so the value of c can only be zero or one, so c=='a' would never be true as 'a' is never equal to 1.

Changing that to

while ((c = getc(stdin)) != EOF)
       ^               ^

can give you the desired result.

You should consider removing FILE* fp because it does nothing at all. It defines a pointer but is never used later, and is likely optimized away by the compiler.

iBug
  • 35,554
  • 7
  • 89
  • 134