Question

This was my own experiment to understand what goes under the hood, what does this program mean to the compiler?

main()
{
  int c;
  printf("%d\n",c);
  printf("%d ", getchar());


  while ((c == getchar()) != EOF){
    putchar(c);
  }
}

When I say c must equal getchar() (c == getchar()), does it not proceed through the while loop? Now I am really confused of my own code, of what c must mean!

Also, in this code:

main()
{
int c;
c = getchar()
while ((c = getchar()) != EOF)
putchar(c);
}

if we modify the int c to int c = getchar(), why cannot we somply write like this:

while (c != EOF)(
    putchar(c);
    c = getchar();
    }

The compiler should know from the previous statement that c = getchar(), why have to write the statement again? Sorry, if I am confused.

Was it helpful?

Solution

while ((c==getchar()) != EOF) {
  ...
}

is a while loop. It evaluates the condition for each iteration of the loop and terminates only if the condition is false.

In your case, the condition is:

(c==getchar()) != EOF)

which is a nonsensical expression, but let's examine it anyway:

First, the program will evaluate:

    getchar()

This grabs a keystroke from standard input. The value of the expression is the value of the key.

Then:

 c==getchar()

This takes the result of getchar() and compares it to whatever is currently in c. In your first program, c is uninitialized, so its value is indeterminate. If c had a defined value, then c==getchar() would evaluate to either true or false. Since c had no defined value, c==getchar() also has no defined value.

Now the program evaluates:

(c==getchar())

Which would still be true or false, except that in your case it is undefined.

The program next considers:

(c==getchar()) != EOF

That is, it compares the true-false value to EOF; this makes no particular sense, and in your case we still have the undefined behavior of an uninitialized c.

In sum, if c were initialized, the expression would fetch a key from standard input and then compare either true or false to EOF. As I said, it is a nonsensical expression.

OTHER TIPS

You're saying you want to look under the hood? Great! Let's dive in :)

while ((c == getchar()) != EOF)

As others have noted, this should be while ((c = getchar()) != EOF). The reason you do assignment (=) rather than equality testing (==) is because you're actually rolling two lines of code into one: c = getchar(); and while(c != EOF). So if the current character being read is k, the program evaluates it in a way kind of like this:

while ((c = getchar()) != EOF)
while ((c = 'k') != EOF)
while (('k') != EOF)
while ('k' != EOF)
while (1) // true

And it has the convenient side effect that c still has k inside for whatever you're planning on doing.

The other problem is here:

int c;
printf("%d\n",c);

printf will complain because you don't have anything assigned to c yet. It's been "declared", but not "initialized." It can't print something that's not there - and if it can, it would surely print something you don't want.

You have an extra equal sign that you need to remove:

while ((c == getchar()) != EOF){

should be

while ((c = getchar()) != EOF){

Here is what is happening. When (c == getchar()) is executed, to begin with c is uninitialized, so it has some garbage value. That garbage value is compared to the next character in the input stream, to see if they are the same. The result of the comparison is going to be 0 (if they are different) or 1 (if they are same). The latter is very unlikely, but it is theoretically possible that by some lucky (?) chance, the garbage value does happen to match the next character in the input stream.

That 0 or 1 is then compared to see whether it matches EOF. Well, EOF is going to be some negative value; that's what it is by definition. Obviously 0 or 1 will never match any negative value, so your loop will be infinite.

As for your second code fragment:

c = getchar();
while ((c = getchar()) != EOF) {

You're not checking whether the first character is EOF, as the value of c after the first getchar() will be immediately replaced by the assignment in the while condition. Assuming that there is a non-EOF first character, your code will work.

As for your third code fragment:

c = getchar();
while (c != EOF) {     // corrected your typo of ( instead of {
    putchar(c);
    c = getchar();
}

The reason why you have to write c = getchar() again inside your while loop is to update the value of c with the second and subsequent characters in the input stream. Otherwise, it will always compare the current value of c, which is the first character in the input stream, to EOF, and this too will be an infinite loop unless the first character does happen to be EOF.

The most concise way of accomplishing what you want is:

int c; while ((c = getchar()) != EOF) putchar (c);

... just like your second code fragment, minus the extra line that does the first getchar() and assigns it to c.

c == getchar() != EOF means

c == getchar() is true if c and the result returned from getchar() are the same.

c == getchar() will always be not equal to EOF (since neither true not false equals EOF) so the program should infinite loop printing the character that randomly showed up here since you never initialized c int c;.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top