Why does getchar let single-character output functions display strings? - c

Just started on K&R and hit:
#include <stdio.h>
/* copy input to output; 1st version */
main()
{
int c;
c = getchar();
while (c != EOF) {
putchar(c);
c = getchar();
}
}
And it just displays what I input, even if it's a string of text.
cacti
cacti
stop repeating what i'm saying
stop repeating what i'm saying
Just like that.
What I don't get is why I can't just instantiate variable c with a string of text and print it the same way. (Ignoring the while loop for the sake the example) Like with:
main()
{
int c;
c = "cacti";
putchar(c);
}
Wherein the output is apparently just 'd'

Here c is only integer which take a character for your case(Although its limits are larger than that).
For first code segment:
getchar() only return a character and you use while loop which take a character from stream and through putchar() it print to console until end of file. You seems to get a line of string and print it but it don't do that way.
In second code segment:
You put a const char* to integer which is not valid(My gcc 4.9.2 does not compile). So it show undefined character (Why print 'd' I don't know, may be compiler issue).
You can do this by:
main()
{
char c[] = "cacti";
puts(c);
}
EDIT
According to getchar() definition:
On success, the character read is returned (promoted to an int value).
The return type is int to accommodate for the special value EOF, which indicates failure.
When you type a single line and press enter then first character read outside of while loop. Than check if it is EOF(End Of File- No more data on the file . You can give EOF by pressing Ctrl+Z in windows and Ctrl+D in linux).
As if it is not encountered EOF, then it entered in while loop and print the singe character(by putchar(c)). After the next line c=getchar() take another character you entered in previous line and check while loop condition while(c!=EOF) being true it entered into loop and print a character. It continues until there found any character to print.
So it makes confuse with puts() which Writes a string in standard output.
Where putchar() Writes a character to the standard output.
According to http://www.cplusplus.com/
Writes the C string pointed by str to the standard output (stdout) and appends a newline character ('\n').

You could use a line-oriented input function to read whole lines. For example:
#include <stdio.h>
int main(void)
{
char line[4096];
while (fgets(line, sizeof(line), stdin) != 0)
fputs(line, stdout);
return 0;
}
For most plausible files, this will read one line at a time into the array of characters, and then write that line out. (If the line length is longer than 4095 characters, then lines will be processed in multiple segments.) If the file contains null bytes, then the material from the null byte to the end of line will be ignored. There are fixes for that — see standard C functions fread() and fwrite(), and POSIX function
getline().
Note that your second example:
int main(void)
{
int c;
c = "cacti";
putchar(c);
}
shouldn't compile without warnings about assigning a character pointer to an integer. When you use putchar() on the result, it probably prints the least significant byte of the address where the string "cacti" is stored. It is pure coincidence that the character printed is d.
The putchar() function only ever prints a single byte (which means a single character in many code sets, but it might only be part of a character in UTF-8).

Related

I dont understand how this code can display a string by using just getchar

I don't understand how this code can display a string by using just getchar, I know that it has something to do with buffers, but I don't understand it.
#include <stdio.h>
int main() {
int c;
puts("Enter text. Include a dot ('.') in a sentence to exit:");
do {
c = getchar();
putchar(c);
} while (c != '.');
return 0;
}
Simply reads each character one by one with getchar and prints immediately with putchar. When encounters a dot (.), prints it and then terminates. Hence it doesn't store more than a single character at a time.
do-while loop
Executes a statement repeatedly, until the value of expression becomes false. The test takes place after each iteration.
getchar
Reads the next character from stdin.
Equivalent to getc(stdin).
putchar
Writes a character ch to stdout. Internally, the character is converted to unsigned char just before being written.
Equivalent to putc(ch, stdout).
Code may look like I/O happens immediately, but certainly both stdin and stdout are buffered by lines.
The first getchar() likely does not return until a line (characters up to and including a '\n') of input happens. Then the first call gets the first characters, 2nd calls gets the second, etc.
Similar for output. Output is not "printed" until a '\n' is sent.
To see output without waiting for a putchar('\n'), follow the putchar() with fflush(stdout);.
To read one character immediately with getchar() takes more work. No answer for that at this time.

Why is getchar() terminating my second getchar() read [duplicate]

I am confused by a program mentioned in K&R that uses getchar(). It gives the same output as the input string:
#include <stdio.h>
main(){
int c;
c = getchar();
while(c != EOF){
putchar(c);
c = getchar();
}
}
Why does it print the whole string? I would expect it to read a character and ask again for the input.
And, are all strings we enter terminated by an EOF?
In the simple setup you are likely using, getchar works with buffered input, so you have to press enter before getchar gets anything to read. Strings are not terminated by EOF; in fact, EOF is not really a character, but a magic value that indicates the end of the file. But EOF is not part of the string read. It's what getchar returns when there is nothing left to read.
There is an underlying buffer/stream that getchar() and friends read from. When you enter text, the text is stored in a buffer somewhere. getchar() can stream through it one character at a time. Each read returns the next character until it reaches the end of the buffer. The reason it's not asking you for subsequent characters is that it can fetch the next one from the buffer.
If you run your script and type directly into it, it will continue to prompt you for input until you press CTRL+D (end of file). If you call it like ./program < myInput where myInput is a text file with some data, it will get the EOF when it reaches the end of the input. EOF isn't a character that exists in the stream, but a sentinel value to indicate when the end of the input has been reached.
As an extra warning, I believe getchar() will also return EOF if it encounters an error, so you'll want to check ferror(). Example below (not tested, but you get the idea).
main() {
int c;
do {
c = getchar();
if (c == EOF && ferror()) {
perror("getchar");
}
else {
putchar(c);
}
}
while(c != EOF);
}
Strings, by C definition, are terminated by '\0'. You have no "C strings" in your program.
Your program reads characters (buffered till ENTER) from the standard input (the keyboard) and writes them back to the standard output (the screen). It does this no matter how many characters you type or for how long you do this.
To stop the program you have to indicate that the standard input has no more data (huh?? how can a keyboard have no more data?).
You simply press Ctrl+D (Unix) or Ctrl+Z (Windows) to pretend the file has reached its end.
Ctrl+D (or Ctrl+Z) are not really characters in the C sense of the word.
If you run your program with input redirection, the EOF is the actual end of file, not a make belief one
./a.out < source.c
getchar() reads a single character of input and returns that character as the value of the function. If there is an error reading the character, or if the end of input is reached, getchar() returns a special value, represented by EOF.
According to the definition of getchar(), it reads a character from the standard input. Unfortunately stdin is mistaken for keyboard which might not be the case for getchar. getchar uses a buffer as stdin and reads a single character at a time. In your case since there is no EOF, the getchar and putchar are running multiple times and it looks to you as it the whole string is being printed out at a time. Make a small change and you will understand:
putchar(c);
printf("\n");
c = getchar();
Now look at the output compared to the original code.
Another example that will explain you the concept of getchar and buffered stdin :
void main(){
int c;
printf("Enter character");
c = getchar();
putchar();
c = getchar();
putchar();
}
Enter two characters in the first case. The second time when getchar is running are you entering any character? NO but still putchar works.
This ultimately means there is a buffer and when ever you are typing something and click enter this goes and settles in the buffer. getchar uses this buffer as stdin.

Is getchar() gets a character from input? [duplicate]

I am confused by a program mentioned in K&R that uses getchar(). It gives the same output as the input string:
#include <stdio.h>
main(){
int c;
c = getchar();
while(c != EOF){
putchar(c);
c = getchar();
}
}
Why does it print the whole string? I would expect it to read a character and ask again for the input.
And, are all strings we enter terminated by an EOF?
In the simple setup you are likely using, getchar works with buffered input, so you have to press enter before getchar gets anything to read. Strings are not terminated by EOF; in fact, EOF is not really a character, but a magic value that indicates the end of the file. But EOF is not part of the string read. It's what getchar returns when there is nothing left to read.
There is an underlying buffer/stream that getchar() and friends read from. When you enter text, the text is stored in a buffer somewhere. getchar() can stream through it one character at a time. Each read returns the next character until it reaches the end of the buffer. The reason it's not asking you for subsequent characters is that it can fetch the next one from the buffer.
If you run your script and type directly into it, it will continue to prompt you for input until you press CTRL+D (end of file). If you call it like ./program < myInput where myInput is a text file with some data, it will get the EOF when it reaches the end of the input. EOF isn't a character that exists in the stream, but a sentinel value to indicate when the end of the input has been reached.
As an extra warning, I believe getchar() will also return EOF if it encounters an error, so you'll want to check ferror(). Example below (not tested, but you get the idea).
main() {
int c;
do {
c = getchar();
if (c == EOF && ferror()) {
perror("getchar");
}
else {
putchar(c);
}
}
while(c != EOF);
}
Strings, by C definition, are terminated by '\0'. You have no "C strings" in your program.
Your program reads characters (buffered till ENTER) from the standard input (the keyboard) and writes them back to the standard output (the screen). It does this no matter how many characters you type or for how long you do this.
To stop the program you have to indicate that the standard input has no more data (huh?? how can a keyboard have no more data?).
You simply press Ctrl+D (Unix) or Ctrl+Z (Windows) to pretend the file has reached its end.
Ctrl+D (or Ctrl+Z) are not really characters in the C sense of the word.
If you run your program with input redirection, the EOF is the actual end of file, not a make belief one
./a.out < source.c
getchar() reads a single character of input and returns that character as the value of the function. If there is an error reading the character, or if the end of input is reached, getchar() returns a special value, represented by EOF.
According to the definition of getchar(), it reads a character from the standard input. Unfortunately stdin is mistaken for keyboard which might not be the case for getchar. getchar uses a buffer as stdin and reads a single character at a time. In your case since there is no EOF, the getchar and putchar are running multiple times and it looks to you as it the whole string is being printed out at a time. Make a small change and you will understand:
putchar(c);
printf("\n");
c = getchar();
Now look at the output compared to the original code.
Another example that will explain you the concept of getchar and buffered stdin :
void main(){
int c;
printf("Enter character");
c = getchar();
putchar();
c = getchar();
putchar();
}
Enter two characters in the first case. The second time when getchar is running are you entering any character? NO but still putchar works.
This ultimately means there is a buffer and when ever you are typing something and click enter this goes and settles in the buffer. getchar uses this buffer as stdin.

Representing EOF in C code?

The newline character is represented by "\n" in C code. Is there an equivalent for the end-of-file (EOF) character?
EOF is not a character (in most modern operating systems). It is simply a condition that applies to a file stream when the end of the stream is reached. The confusion arises because a user may signal EOF for console input by typing a special character (e.g Control-D in Unix, Linux, et al), but this character is not seen by the running program, it is caught by the operating system which in turn signals EOF to the process.
Note: in some very old operating systems EOF was a character, e.g. Control-Z in CP/M, but this was a crude hack to avoid the overhead of maintaining actual file lengths in file system directories.
EOF is not a character. It can't be: A (binary) file can contain any character. Assume you have a file with ever-increasing bytes, going 0 1 2 3 ... 255 and once again 0 1 ... 255, for a total of 512 bytes. Whichever one of those 256 possible bytes you deem EOF, the file will be cut short.
That's why getchar() et al. return an int. The range of possible return values are those that a char can have, plus a genuine int value EOF (defined in stdio.h). That's also why converting the return value to a char before checking for EOF will not work.
Note that some protocols have "EOF" "characters." ASCII has "End of Text", "End of Transmission", "End of Transmission Block" and "End of Medium". Other answers have mentioned old OS'es. I myself input ^D on Linux and ^Z on Windows consoles to stop giving programs input. (But files read via pipes can have ^D and ^Z characters anywhere and only signal EOF when they run out of bytes.) C strings are terminated with the '\0' character, but that also means they cannot contain the character '\0'. That's why all C non-string data functions work using a char array (to contain the data) and a size_t (to know where the data ends).
Edit: The C99 standard §7.19.1.3 states:
The macros are [...]
EOF
which expands to an integer constant expression, with type int and a negative value, that is returned by several functions to
indicate end-of-file, that is, no more input from a stream;
No. EOF is not a character, but a state of the filehandle.
While there are there are control characters in the ASCII charset that represents the end of the data, these are not used to signal the end of files in general. For example EOT (^D) which in some cases almost signals the same.
When the standard C library uses signed integer to return characters and uses -1 for end of file, this is actually just the signal to indicate than an error happened. I don't have the C standard available, but to quote SUSv3:
If the end-of-file indicator for the stream is set, or if the stream is at end-of-file, the end-of-file indicator for the stream shall be set and fgetc() shall return EOF. If a read error occurs, the error indicator for the stream shall be set, fgetc() shall return EOF, and shall set errno to indicate the error.
I've read all the comments. It's interesting to notice what happens when you print out this:
printf("\nInteger = %d\n", EOF); //OUTPUT = -1
printf("Decimal = %d\n", EOF); //OUTPUT = -1
printf("Octal = %o\n", EOF); //OUTPUT = 37777777777
printf("Hexadecimal = %x\n", EOF); //OUTPUT = ffffffff
printf("Double and float = %f\n", EOF); //OUTPUT = 0.000000
printf("Long double = %Lf\n", EOF); //OUTPUT = 0.000000
printf("Character = %c\n", EOF); //OUTPUT = nothing
As we can see here, EOF is NOT a character (whatsoever).
The EOF character recognized by the command interpreter on Windows (and MSDOS, and CP/M) is 0x1a (decimal 26, aka Ctrl+Z aka SUB)
It can still be be used today for example to mark the end of a human-readable header in a binary file: if the file begins with "Some description\x1a" the user can dump the file content to the console using the TYPE command and the dump will stop at the EOF character, i.e. print Some description and stop, instead of continuing with the garbage that follows.
This is system dependent but often -1. See here
I think it may vary from system to system but one way of checking would be to just use printf
#include <stdio.h>
int main(void)
{
printf("%d", EOF);
return 0;
}
I did this on Windows and -1 was printed to the console. Hope this helps.
The value of EOF can't be confused with any real character.
If a= getchar(), then we must declare a big enough to hold any value that getchar() returns. We can't use char since a must be big enough to hold EOF in addition to characters.
The answer is NO, but...
You may confused because of the behavior of fgets()
From http://www.cplusplus.com/reference/cstdio/fgets/ :
Reads characters from stream and stores them as a C string into str until (num-1) characters have been read or either a newline or the end-of-file is reached, whichever happens first.
I have been researching a lot about the EOF signal. In the book on Programming in C by Dennis Ritchie it is first encountered while introducing putchar() and getchar() commands.
It basically marks the end of the character string input.
For eg. Let us write a program that seeks two numerical inputs and prints their sum. You'll notice after each numerical input you press Enter to mark the signal that you have completed the iput action. But while working with character strings Enter is read as just another character ['\n': newline character]. To mark the termination of input you enter ^Z(Ctrl + Z on keyboard) in a completely new line and then enter. That signals the next lines of command to get executed.
#include <stdio.h>
int main()
{
char c;
int i = 0;
printf("INPUT:\t");
c = getchar();
while (c != EOF)
{
++i;
c = getchar();
};
printf("NUMBER OF CHARACTERS %d.", i);
return 0;}
The above is the code to count number of characters including '\n'(newline) and '\t'( space) characters. If you don't wanna count the newline characters do this :
#include <stdio.h>
int main()
{
char c;
int i = 0;
printf("INPUT:\t");
c = getchar();
while (c != EOF)
{
if (c != '\n')
{
++i;
}
c = getchar();
};
printf("NUMBER OF CHARACTERS %d.", i);
return 0;}.
NOW THE MAIN THINK HOOW TO GIVE INPUT. IT'S SIMPLE:
Write all the story you want then go in a new line and enter ^Z and then enter again.
There is the constant EOF of type int, found in stdio.h. There is no equivalent character literal specified by any standard.

`getchar()` gives the same output as the input string

I am confused by a program mentioned in K&R that uses getchar(). It gives the same output as the input string:
#include <stdio.h>
main(){
int c;
c = getchar();
while(c != EOF){
putchar(c);
c = getchar();
}
}
Why does it print the whole string? I would expect it to read a character and ask again for the input.
And, are all strings we enter terminated by an EOF?
In the simple setup you are likely using, getchar works with buffered input, so you have to press enter before getchar gets anything to read. Strings are not terminated by EOF; in fact, EOF is not really a character, but a magic value that indicates the end of the file. But EOF is not part of the string read. It's what getchar returns when there is nothing left to read.
There is an underlying buffer/stream that getchar() and friends read from. When you enter text, the text is stored in a buffer somewhere. getchar() can stream through it one character at a time. Each read returns the next character until it reaches the end of the buffer. The reason it's not asking you for subsequent characters is that it can fetch the next one from the buffer.
If you run your script and type directly into it, it will continue to prompt you for input until you press CTRL+D (end of file). If you call it like ./program < myInput where myInput is a text file with some data, it will get the EOF when it reaches the end of the input. EOF isn't a character that exists in the stream, but a sentinel value to indicate when the end of the input has been reached.
As an extra warning, I believe getchar() will also return EOF if it encounters an error, so you'll want to check ferror(). Example below (not tested, but you get the idea).
main() {
int c;
do {
c = getchar();
if (c == EOF && ferror()) {
perror("getchar");
}
else {
putchar(c);
}
}
while(c != EOF);
}
Strings, by C definition, are terminated by '\0'. You have no "C strings" in your program.
Your program reads characters (buffered till ENTER) from the standard input (the keyboard) and writes them back to the standard output (the screen). It does this no matter how many characters you type or for how long you do this.
To stop the program you have to indicate that the standard input has no more data (huh?? how can a keyboard have no more data?).
You simply press Ctrl+D (Unix) or Ctrl+Z (Windows) to pretend the file has reached its end.
Ctrl+D (or Ctrl+Z) are not really characters in the C sense of the word.
If you run your program with input redirection, the EOF is the actual end of file, not a make belief one
./a.out < source.c
getchar() reads a single character of input and returns that character as the value of the function. If there is an error reading the character, or if the end of input is reached, getchar() returns a special value, represented by EOF.
According to the definition of getchar(), it reads a character from the standard input. Unfortunately stdin is mistaken for keyboard which might not be the case for getchar. getchar uses a buffer as stdin and reads a single character at a time. In your case since there is no EOF, the getchar and putchar are running multiple times and it looks to you as it the whole string is being printed out at a time. Make a small change and you will understand:
putchar(c);
printf("\n");
c = getchar();
Now look at the output compared to the original code.
Another example that will explain you the concept of getchar and buffered stdin :
void main(){
int c;
printf("Enter character");
c = getchar();
putchar();
c = getchar();
putchar();
}
Enter two characters in the first case. The second time when getchar is running are you entering any character? NO but still putchar works.
This ultimately means there is a buffer and when ever you are typing something and click enter this goes and settles in the buffer. getchar uses this buffer as stdin.

Resources