-5

I read few questions on Stack Overflow but everyone here is explaining that has already been explained in K&R. I want to ask when the below program runs. Then if I input my name in the console then it get printed in the next line. Firstly this function's name is getchar why it doesn't take just one character 'a' or any other? I get correct output irrespective of how long my input is.

I wrote 'adfsajfsjssadfsa.......up to to 100 characters and putchar copied it exactly'. Also book is using int. I know int can hold data up to 4 bytes much bigger than char but what's the use of providing data types in C if we can use any of them.

Why does putchar print it to next line? Is it built this way to always print the output in next line? I wrote adfsajfsjssadfsa.......upto to 100 characters and putchar copied it exactly when will a situation come that I would get error and integer c won't be able to hold that big data. How many characters?

#include <stdio.h>
int main() 
{
    int c; 
    c=getchar();
    while(c!=EOF){
        putchar(c);
        c=getchar();
    }
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
HELP PLZ
  • 41
  • 1
  • 9
  • 2
    search your book for the meaning of `while` – pqnet Aug 22 '14 at 19:46
  • getchar isn't buffered. Well not the way you describe it at least. The terminal is the one buffering it. I put that in an answer but didn't have time to send it. (I disagree with this duplication close, FWIW). – Per Johansson Aug 22 '14 at 20:07
  • 2
    When a neophyte thinks that the compiler, language, or library is broken, they should stop to think that it's most likely their own understanding that is flawed. – Jim Balter Aug 22 '14 at 20:16
  • This would've been a better question to link: http://stackoverflow.com/questions/17552458/theory-behind-getchar-and-putchar-functions – Per Johansson Aug 22 '14 at 20:21
  • @Jim Balter Neophytes do not have a monopoly on " thinks that the compiler, language, or library is broken". It was many years before myself was even > 50% right. – chux - Reinstate Monica Aug 22 '14 at 23:51
  • @chux I didn't claim there is such a monopoly, but it's neophytes who are most likely to make these sorts of claims while at the same time being least likely to be right. I learned early on to be skeptical of my own inferences and to recognize "That can't happen!" to simply be a reflection of my own ignorance and blindness; I guess it took longer for you. – Jim Balter Aug 23 '14 at 01:00
  • @Jim Balter 1st 4 years: maybe 1 for 20. Middle years 1/1. Last 9 years, 15/20. (Embedded environments have lots of issues) :-) – chux - Reinstate Monica Aug 23 '14 at 01:12
  • @PerJohansson "getchar isn't buffered." -- Yes, it is. From section 7.19.3 of the standard: *As initially opened, the standard error stream is not fully buffered; the standard input and standard output streams are fully buffered if and only if the stream can be determined not to refer to an interactive device.* ... "The terminal is the one buffering it." -- On some systems but not all. On Linux the line is buffered both in the terminal driver and in the stdin buffer. – Jim Balter Aug 23 '14 at 01:14
  • @JimBalter yeah, that's why I added the "not the way you described it". And since it's not getchar buffering it has to be the terminal... – Per Johansson Aug 23 '14 at 07:46
  • I realised I sound a quite arrogant, sorry about that. – Per Johansson Aug 23 '14 at 07:57
  • @PerJohansson getchar *is* buffered the way user3121023 described it; you were simply wrong to say otherwise. "since it's not getchar buffering it" -- Yes it *is* getchar -- or rather the stdio library that getchar is part of -- buffering it. You seem not to understand a word of what I quoted from the standard, or how stdio works. (I worked extensively on the UNIX C library once upon a time and I do.) – Jim Balter Aug 23 '14 at 09:20
  • More relevant text from the standard: *When a stream is unbuffered, characters are intended to appear from the source or at the destination as soon as possible. Otherwise characters may be accumulated and transmitted to or from the host environment as a block.... When a stream is line buffered, characters are intended to be transmitted to or from the host environment as a block when a new-line character is encountered.* -- stdin is normally line-buffered when reading from a terminal. – Jim Balter Aug 23 '14 at 09:28
  • @JimBalter I'm sorry but you're wrong. Try running the above code in your terminal, type a character and then press `ctrl-D`. You'll notice getchar will return that character immediately. No newlines involved. Or run it with `stty raw`. The buffering is all done in the terminal. – Per Johansson Aug 23 '14 at 10:25
  • Felt I need to clarify that "all" isn't strictly correct since `stdin` will indeed read all the available data and store it in a buffer. But that's not what's preventing `getchar` from returning earlier than the newline. The terminal buffer is the one causing that. – Per Johansson Aug 23 '14 at 14:35
  • "stdin will indeed read all the available data and store it in a buffer." -- IOW, getchar is buffered. Sheesh. I'm done with this. – Jim Balter Aug 23 '14 at 18:27

2 Answers2

2
  1. You are calling getchar and putchar multiple times (because they are inside a loop) so they get and print multiple characters.
  2. You MUST use an int variable when using getchar, because getchar can return any character or EOF. EOF isn't a character, so it doesn't fit in a char, and it represents the end of the file.
Mabus
  • 1,418
  • 12
  • 20
  • Detail: `getchar()`, like `getc()` and `fgetc()` return an `unsigned char` or `EOF`. `EOF` _does_ fit in a `char`, when `char` is signed, but since `EOF < 0` it does not fit in an `unsigned char`. Still agree it is best to use an `int` for the return value. – chux - Reinstate Monica Aug 22 '14 at 23:46
  • @chux EOF is a negative constant of type `int`. There is no requirement that it can fit in a `char`. – Jim Balter Aug 23 '14 at 01:07
  • @Jim Balter Agreed `EOF` is not required to fit in a `char`. A better comment would have been "`EOF` _may_ fit in a `char`, when `char` is signed". – chux - Reinstate Monica Aug 23 '14 at 01:17
  • @chux I think Mabus put it best: "You MUST use an int variable." ... as with many such "must"s in C, your program *might* work if you violate it. In this case it's a matter of implementation-specific behavior rather than undefined behavior, but it would be foolish to write code that only works on certain implementations when it is easy enough to make it strictly compliant. – Jim Balter Aug 23 '14 at 01:22
  • @Mabus what is a character? 'A' is a character then how come 'dog' is stored in c and then printed by by putchar...it should just store 'd' and then print 'd' if getchar gets only one character ? – HELP PLZ Aug 23 '14 at 02:48
0

Variable c will always contain just 1 character, which is int. You are overwriting previous value with return value of a function getchar in each iteration of a loop.

Also try to avoid duplicate code by rewriting the while loop. You can call function getchar and assign value to variable c inside the while condition:

while ((c = getchar()) != EOF) {
    putchar(c);
}
David Ferenczy Rogožan
  • 23,966
  • 9
  • 79
  • 68
  • 1
    The usual idiom is `while ((c = getchar()) != EOF) { /* ... */ }` – Keith Thompson Aug 22 '14 at 19:53
  • 1
    Yeah, you are right, but both variants are valid. I'll update my answer. Thanks. – David Ferenczy Rogožan Aug 22 '14 at 20:01
  • 2
    The trouble with the `do ... while` loop is that you try to do `putchar` on the EOF value, which likely appears as ÿ (y-umlaut, U+00FF, LATIN SMALL LETTER Y WITH DIAERESIS). The `while` loop avoids that problem. – Jonathan Leffler Aug 22 '14 at 20:10
  • It's unfortunate that someone upvoted your comment that both variants are valid, when they obviously do different things. `do { c = getchar(); if (c == EOF) break; putchar(c); } while(1);` is valid and does the same thing as the first loop but is awkward. – Jim Balter Aug 22 '14 at 20:13