Understanding putchar loop - c

This code takes multiple fs and prints only 1. Can someone please explain to me why this code does not print two fs? putchar appears twice while not EOF. I have been staring at it for hours and I do not understand how it prints only 1 f.
The code is functioning correctly. I just do not understand how it works step by step.
/* A program that takes input of varied 'f's and out puts 1 f */
#include <stdio.h>
main()
{
int c;
while ((c = getchar()) != EOF)
{
if (c == 'f')
{
putchar(c);
}
while (c == 'f')
{
c = getchar();
}
if (c != EOF) putchar(c);
}
}
Thanks

I'll step through with comments in the code; for f (or in reality f\n) as input:
#include <stdio.h>
main()
{
int c;
while ((c = getchar()) != EOF) // You type f and hit return key (remember this)
{
if (c == 'f') // c contains 'f' is true
{
putchar(c); // print 'f'
}
while (c == 'f') // c == 'f' is true
{
c = getchar(); // '\n' is buffered on stdin from return key
// so getchar() returns '\n'. So c will be set to '\n'
// It goes back to the while loop and checks if c == 'f'
// but it's not, it's '\n'! So this will run once only.
}
if (c != EOF) putchar(c); // '\n' != EOF, so print '\n' newline, back to loop
}
}
Thus giving f\n as input will yield the output f\n
In the case of input fffff (in reality fffff\n), see below:
#include <stdio.h>
main()
{
int c;
while ((c = getchar()) != EOF) // You type fffff and hit return key
{
if (c == 'f') // c contains 'f' is true, first 'f'
{
putchar(c); // print 'f'
}
while (c == 'f') // First loop, c == 'f'
// Second loop, c == 'f'
// Last loop, c == '\n', so false
{
c = getchar(); // First loop: 'ffff\n' is still buffered on stdin
// c = 'f', loop again
// Last loop: c = '\n'
}
if (c != EOF) putchar(c); // '\n' != EOF, so print '\n' newline, back to loop
}
}
You see that your inner while loop will eat all the f until you hit \n, thus the same affect as above.

if(c == 'f')
putchar(c);
This prints one f, the one you see.
while(c == 'f')
getchar(c);
This is where the f disappears. If you just used putchar(c) before, that means that the loop will execute at least once because c == f. So the f is gone (c != f)
Finally, you just use putchar(c) on the first character which is not f.

Related

Why having getchar() assigned to a variable in a while loop condition leads to output of 0?

So currently I'm learning C from the C programming language 2nd edition book and it says that:
while (c = getchar() != EOF) {
}
is identical to:
while (c != EOF) {
c = getchar();
}
However, when I run the code I just had written:
#include <stdio.h>
int main() {
char c;
int times;
while (c = getchar() != EOF) {
if (c == 'a') {
++times;
}
}
printf("%d\n", times);
}
The value of times it outputs is 0 instead of actual value of times I typed in 'a' character.
Now in this code, it works fine:
#include <stdio.h>
int main() {
char c;
int times;
while (c != EOF) {
c = getchar();
if (c == 'a') {
++times;
}
}
printf("%d\n",times);
}
and if I type a 3 times, the value it outputs is 3.
Precedence!
c = getchar() != EOF
means
c = ( getchar() != EOF ) // Assigns `0` or `1` to `c`.
but you want
( c = getchar() ) != EOF
Also note that c needs to be an int.
This means you could use
for (int c; ( c = getchar() ) != EOF; ) {
...
}
but I prefer
while (1) {
int c = getchar();
if (c == EOF)
break;
...
}
Operator precedence.
!= operator is higher in precedence than =, so your expression is equivalent to:
while (c = (getchar() != EOF))
use a parenthesis around c=getchar() and it will work.

getchar() in C with while looping not printing afterwards

I don't understand why the printf() call after the while loop does not get executed?
int main(){
while((getchar()) != EOF){
characters ++;
if (getchar() == '\n'){
lines++;
}
}
printf("lines:%8d\n",lines);
printf("Chars:%8d",characters);
return 0;
}
I think you are trying to do that
#include<stdio.h>
int main()
{
int characters=0,lines=0;
char ch;
while((ch=getchar())!= EOF)
{
if (ch == '\n')
lines++;
else
{
characters++;
while((ch=getchar())!='\n'&&ch!=EOF); //is to remove \n after a character
}
}
printf("lines:%8d\n",lines);
printf("Chars:%8d",characters);
return 0;
}
Output:
a
s
d
f
^Z
lines: 1
Chars: 4
Process returned 0 (0x0) execution time : 8.654 s
Press any key to continue.
Note: ^Z(ctrl+z) is to send EOF to stdin (in windows)
You have to be careful of you're treatment in the while loop. Indeed, you are missing every caracter read in your while statement. You have to save this input, in order to use it afterwards.
The proper syntax would be while(( c = getchar()) != EOF)
You are probably looking for something like this:
#include <stdio.h>
int main()
{
int characters = 0;
int lines = 0;
int c;
while ((c = getchar()) != EOF) {
characters++;
if (c == '\n') {
lines++;
characters--; // ignore \n
}
}
printf("lines: %8d\n", lines);
printf("Chars: %8d", characters);
return 0;
}
while ((c = getchar()) != EOF) might look a bit confusing.
Basically it calls getchar, puts the returned valuee into c ands then checks if c equals EOF.

Understanding EOF and break

I am trying to write a program which replaces a string of one or more tabs by a single tab.
Here's what I wrote:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int c;
while ((c = getchar()) != '\n')
{
if (c == 9)
{
while((c=getchar())== 9)
putchar(' ');
if (c != 9)
break;
}
putchar(c);
}
}
I compared it to newline because I don't get EOF and pressing ctrl-z does nothing, atleast on Windows.
Well the output prints spaces instead of tabs. Can someone point out what am I doing wrong?
There is no need to break, in fact, when you use break inside a for/while you exit from the loop (not what you want), if you want to allow only one tab use a sentinel and continue if the previous character is also a tab:
int c, tab = 0;
while (((c = getchar()) != '\n') && (c != EOF)) {
if (c == '\t') {
if (tab == 1) continue;
tab = 1;
} else {
tab = 0;
}
putchar(c);
}
Press CTRL+ Z + Intro to send EOF in Windows.
its because you write putchar(' ').
its an error. write putchar('\t') instead.
there is no such char as ' '. this is 4 spaces.

C programming, Can anyone explain this?

#include <stdio.h>
int main() {
int c;
while ((c = getchar()) != EOF) {
if (c == '\t')
printf("\\t");
else if (c == '\b')
printf("\\b");
else if (c == '\\')
printf("\\\\");
else
putchar(c);
}
return 0;
}
In this case for an input of
hi how are you\doing
I get an output
hi\thow\tare\tyou\\doing
#include <stdio.h>
int main() {
int c;
while ((c = getchar()) != EOF) {
if (c == '\t') {
c = '\b';
printf("\\t");
}
if (c == '\b') {
c = '\b';
printf("\\b");
}
if (c == '\\') {
c = '\b';
printf("\\\\");
}
putchar(c);
}
return 0;
}
When I run this program with an input
hi how are you\doing
(The large spaces being tabs)
I get this output
hi\t\how\t\are\t\you\doing
Code:
#include <stdio.h>
int main() {
int c;
c = '\b';
putchar(c);
return 0;
}
On running this,
I get nothing. No output. Back to the shell prompt.
To be more precise, in the first program I get the output I want, but in the second program I get the backslashes after every \t but not after the \ I would expect \\\ to be the output looking at how \t became \t\, is '\b' causing it? if it is, how does it work? but if so why doesn't the same happen in the third program?
Ran this on rasbian default gcc compiler and mingw msys-gcc package for windows.
The reason the second program is behaving that way is because you are entering more than one if block:
if (c == '\t') {
c = '\b';
printf("\\t");
}
if (c == '\b') {
c = '\b';
printf("\\b");
}
if (c == '\\') {
c = '\b';
printf("\\\\");
}
putchar(c);
When you encounter a tab, the first block is entered where it prints \t to the screen then changes c to a backspace.
The second block is then entered because c is a backspace (because you just changed it to be that). That block then prints \b to the screen, so now you have \t\b on the screen.
When you then call putchar to write the backspace, the b will get overwritten by the next character. So when the next character is written you then have \t\ on the screen.
So the problem here is that you're testing c multiple times and potentially changing it in between. The reason this happens only with the tab is because you check for the tab first, then the backspace, then the backslash.
If you use else if instead of if, you won't enter multiple blocks:
if (c == '\t') {
c = '\b';
printf("\\t");
}
else if (c == '\b') {
c = '\b';
printf("\\b");
}
else if (c == '\\') {
c = '\b';
printf("\\\\");
}
putchar(c);
With this change, given the original input, the output will be:
hi\how\are\you\doing

Counting input characters in C

I have just started learning C, been reading a C textbook by Keringhan and Ritchie. There was this example in the textbook, counting characters from user input. Here's the code:
#include <stdio.h>
main()
{
long nc;
nc = 0;
while(getchar() != EOF) {
if (getchar() != 'q')
++nc;
else
break;
}
printf("%ld\n", nc);
}
The problem is, when I execute the code, if I input only one character per line, when I input "q" to break, it doesn't do so. I have to type some word per line, only after that it will break the loop. Also, it only counts the half of the characters of the word. I.e. if I input
a
b
russia
it will only print '5' as final result.
Could you please explain to me why is this happening?
This works, but only when you finish off with an Enter. So, this will count the characters until the first "q" appears. That is just how getchar() and getc(stdin) work.
#include <stdio.h>
int main() {
char c = 0;
long count = 0;
short int count_linebreak = 1; // or 0
while((c = getchar()) != EOF) {
if(c != 'q' && (count_linebreak || (!count_linebreak && c != '\n'))) {
++count;
}else if(c == 'q') {
printf("Quit\n");
break;
}
}
printf("Count: %ld\n",count);
return 0;
}
A StackOverflow question about reading stdin before enter
C read stdin buffer before it is submit

Resources