Confusion about two simple character counting programs in C [duplicate] - c

This question already has answers here:
For vs. while in C programming?
(19 answers)
Closed 4 years ago.
The goal is to write a simple character counting program in C. If written like this:
#include <stdio.h>
main()
{
long nc;
for(nc = 0; getchar() != EOF; ++nc)
printf("%ld\n", nc);
}
the last number listed in its output will be the correct number of characters. However, if written like this:
#include <stdio.h>
main()
{
long nc;
nc = 0;
while(getchar() != EOF)
{
++nc;
printf("%ld\n", nc);
}
}
the last number in its output will always be larger by one than the true number of characters in the input string. I learned that this is because pressing Enter after inputting the desired string introduces a newline character which gets counted and produces the error. To eliminate that error is trivial, but my question is why doesn't the same problem occur in the program written above?
For example, the first program will correctly output 0 if ran without input. The second one however will output 1 in the same scenario. Why the difference?

All numbers are larger by one in the second loop, not just the last.
Your for-loop is equivalent to
nc = 0;
while (getchar() != EOF)
{
printf("%ld\n", nc);
++nc;
}
As you can see, it increments after printing, and your while increments before printing.

The difference is due to the order in which the statements are executed in both the scenario.
In case of for loop, the order is:
(1) (2) (4)
|----| |---------------| |
for(nc = 0; getchar() != EOF; ++nc)
printf("%ld\n", nc); --------------- (3)
and in case of while loop, the order is:
nc = 0; ------------------- (1)
while(getchar() != EOF) --------------- (2)
{
++nc; -------------------- (3)
printf("%ld\n", nc); ------------ (4)
}
So, in case of for loop the ++nc is last executed in every iteration i.e. after printf() and in case of while loop the ++nc is executed before the printf() in every iteration. Hence, you are observing the difference.

Related

putchar and printf not behaving as expected

I'm working through some of the exercises in K&R. Exercise 1-6 asks for verification that the expression getchar() != EOF is either 0 or 1. I understand why it is, but the code I wrote to prove it didn't work as expected. I wrote the following two snippets:
Version 1:
int main(void)
{
int c;
while (c = getchar() != EOF)
{
putchar(c);
}
printf("%d at EOF\n", c);
return 0;
}
Version 2:
int main(void)
{
int c;
while (c = getchar() != EOF)
{
printf("%d\n", c);
}
printf("%d at EOF\n", c);
return 0;
}
My questions:
When I type in a character and hit enter with version one, why do I not see either a 0 or 1 on the screen? Instead, my cursor moves to the first position on next line, which is otherwise empty. I though putchar would send c to stdout.
While the use of printf in the second version does produce a 0 or 1 appropriately, it duplicates the 1 for each non-EOF character (I see the number 1 on two consecutive lines for each character I input). Why?
Many thanks in advance for your thoughts. If there is a reference that you think would help, please send a link.
CLARIFICATION:
I know I'm assigning c a value of either 0 or 1. That's what I want to do, and it's what the exercise wants. That's also why I don't have parentheses around c = getchar(). My question deals more with understanding why the output isn't what I had expected. Sorry for any confusion.
The assignment operator = has lower precedence than the inequality operator !=.
So this:
while (c = getchar() != EOF)
Is parsed as:
while (c = (getchar() != EOF))
So then c is assigned the boolean value 1 if getchar is not EOF and 0 if it does return EOF.
As a result, the first program print the character for the ASCII code 1, which is a non-printable character. That's why you don't see anything. The second program, using the %d format specifier to printf, converts the number 1 to its string representation.
You need parenthesis to have the result of getchar assigned to c:
while ((c = getchar()) != EOF)
EDIT:
To further clarify the output you're getting, in both programs the variable c has the value 1 inside of each while loop. The difference here is that putchar is printing the character with the ASCII value of 1 (an unprintable character), while printf with %d print the textual representation of the value 1, i.e. 1.
If you changed the printf call to this:
printf("%c", c);
You would get the same output as using putchar.
As for the printing of 1 twice for each character, that is because you're actually entering two characters: the key you press, plus the enter key. When reading from the console, the getchar function doesn't return until the enter key is pressed.

Counting number of user input using getchar() gives double the expected result, why?

In the following example, from the book "C programming", when input characters, the program count twice.
main(){
long nc;
nc = 0;
while (getchar() != EOF)
++nc;
printf("%ld\n", nc);
}
OUTPUT:
a
b
c
d
e
f
12
What's wrong?
I'am using Ubuntu and the gcc compiler.
It's counting properly. getchar() is considering the ENTER key press also, as a newline \n. So 6 user inputs and 6 newlines. Counts match.
If you don't want the newlines to be counted as inputs, you need to increment the counter when the getchar() return value is not \n, something like
while ( (c = getchar()) != EOF) {
if ( c != '\n') ++nc;
}
will get the job done. Note, c should be of type int to be able to handle EOF.
That said, as per C99 or C11, for a hosted environment, the signature of main() should at least be int main(void) to conform to the standard.

How EOF really works in this one?

#include<stdio.h>
#include<conio.h>
int main() {
long nc;
nc = 0;
while (getchar()!= EOF){
++nc;
printf("%ld\n", nc);
}
return 0;
}
My question is: When I input a number or a character, it increments twice >.<
for example: I ran the program, I typed 1, then its going to output
1
2
can someone please tell me why >< cause isn't it suppose to just increment 1? And the value of nc that the program is gonna show is 1? Then its going to become 2 when i enter another number or character?
After entering any number you are pressing Enter key.
and as '\n' != EOF so it is running two times.
int main() {
long nc;
nc = 0;
while (getchar()!= '\n'){ // check for enter key here.
++nc;
printf("%ld\n", nc);
}
return 0;
}
When you input a number and press Enter key, an additional \n character passed to the standard input buffer. getchar reads that number leaving behind \n in the buffer. On next iteration of loop getchar reads \n before pressing any character by you and hence inside while for second time.Hence value is printed twice as \n is not there.
Use below while condition and this shall fix the issue.
while(getchar() != '\n');
This will eat up any number of \n.

For loop iteration issue

I have tried many variations of this code, including using a scanf function, and every time it increments by 2 points instead of one. Here is the code:
#include <stdio.h>
int main(void)
{
double nc;
for(nc = 0; getchar() != EOF; ++nc)
printf("%.0f\n", nc);
}
This is the output that I get. The input that I used was qwerty, and the outputs are numbers 0-11 instead of 0-5 as expected.
q
0
1
w
2
3
e
4
5
r
6
7
t
8
9
y
10
11
One thought I had was that when I press enter, it is counted as a value for getchar along with the character I entered and this causes the loop to run through two iterations. Can anybody further explain this concept or provide links to more information about it for me?
The trailing newline from previous getchar is taken up as input for next getchar
So use,
for(nc = 0; getchar() != EOF; ++nc)
{
printf("%.0f\n", nc);
getchar(); //"eat" the trailing newline
}

Is printf supposed to print out a 'long' value? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why doesn’t getchar() recognise return as EOF in windows console?
I'm trying to print out the value in the variable 'nc' in the next program:
int main()
{
long nc;
nc = 0;
while (getchar() != EOF)
++nc;
printf("%ld\n", nc);
}
Please tell me why is it not printing?
You don't have brackets in your while loop (this is why not using brackets leads to error prone software). Therefore, the value is getting incremented, but not printing.
Try:
int main(int argc, char** argv)
{
long nc;
nc = 0;
while (getchar() != EOF)
{ // ADD THIS
++nc;
printf("%ld\n", nc);
} // AND THIS
}
otherwise, your code is essentially doing:
int main(int argc, char** argv)
{
long nc;
nc = 0;
while (getchar() != EOF)
{
++nc; // ENDLESSLY ADDING
}
printf("%ld\n", nc); // NEVER REACHED DUE TO WHILE LOOP.
}
Your while loop will continue to loop until you end the input using Control-D on Unix or Control-Z, Return on Windows. It will do this without printing anything because you did not use braces around the ++nc and printf.
You may also have problems with printf if you did not #include <stdio.h> at the top of your program. If the compiler does not know that printf is a varargs function, it will not format the argument list correctly when calling it.
after entering some inputs like
1
2 4
u must type ctrl + D since its the EOF ASCII equivalent.
Else modify the progeam and put
while(getchar()!='\r') (until you hit Enter)
What do you mean? It works:
./a.out
asdfsdfasdfasdfasddddddddddddddddddddddd
41
echo "Try to count this" | ./a.out
18
you have to stop reading characters from stdin by stopping the while loop of getchar
and then you will see the nc value printed
To do
EOF = CTRL + D (for Linux)
EOF = CTRL + Z (for Windows)

Resources