#include <stdio.h>
int main()
{
int c;
while ( (c = getchar()) != EOF )
{
if (c >= 65 && c <= 90)
c += 32;
else if (c >= 97 &&c <= 122)
c -= 32;
putchar(c);
}
return 0;
}
In the code how is the input interpreted, processed and printed?
For example, if we input abcde we get output ABCDE. As we are processing input character by character, we should get the output character by character but we get output once we press enter. Till we press enter where is the output store.
what are the functions?
getchar() is a function that is used to get a single character from
the console.
putchar() is a function that is used to return the character written
as an unsigned char cast to an int.
#include <stdio.h>
int main()
{
int c;
while ( (c=getchar()) != EOF ){
if (c >= 65 && c <= 90)
c += 32;
else if (c >= 97 &&c <= 122)
c -= 32;
putchar(c);
}
return 0;
}
c is int so when you read character from keyboard it stores it as integer not character.
checkout ASCII.
so 65 = A, 90 = Z, 97 = a, 122 = z,
Here is what i understood from the code:
create variable c to store our character.
get character from user and store it to c.
while c is not equal to EOF(end of file)
if c is greater than or equal to 65 and c is less than or equal to 90
add 32 to c
or else if c is greater than 97 and c is less than or equal to 122
minus 32 from c
return c value into character and print it.
At first, I would appreciate that you have asked such a good question that most of the programmer won't even think about. In this article, I tried best to solve the matter.
Queue: Follows the principal First In First Out. The principal is similar to the priority followed while a queue of people waiting to buy new iPhones.
Input stream behaves like a queue. Consider it as a Scooby Doo. Even what It has eaten is enough for it's day it won't stop eating. If someone offers two tonnes of food in the breakfast, Scooby will eat all the breakfast and still asks for the Lunch.
The input stream is similar to Scooby Doo. Look this code!
char c=getchar();
Here one character is enough for c but when you run this code. You can type as many characters as you want in the console but no matter what when you press enter your enter: c will assign to the first character you had typed.
But notice that checking for EOF is bad practice because of so many reasons I will list the reasons at the end.
When coming to your Question!. Why is the character not printed one by one?
Studying about stream itself is a big area. So just for your convenience think, that input stream will have some hidden file(Queue) to store whatever character you have typed.
Typing character in the stream is like a machine gun firing continuously. There is no option you have to wait for the machine gun to stop firing for doing the counter-attack.
Likewise, while you are typing the character in the stream the file will simply push each character into it. Once you have typed enter or the EOF command 'Cntl+D'.
Then your code will look into the file character by character(Remember the principal first IN). If a condition meets it will stop executing there and it won't care about the next the remaining characters in the file.
In your case, it will look all the characters in the file after the user types enter or EOF command and it will change their cases(upper to lower and vice-versa)
As I promised!
Why one should not check for EOF!
One reason is that the keystroke that creates an end-of-file condition from the
keyboard is not standard, but differs between platforms.
Another reason is that terminating the program is best done more explicitly
(e.g. with a "quit" command).
A third reason is that other error conditions might arise, and this check will not detect them.
So try to avoid it.
stdin and stdout are buffered streams. You can set them to be unbuffered, but that can cause a significant performance hit. And, even if you set them to unbuffered, it still may not be effective from a terminal interface because the terminal often does it's own buffering.
See this for more info:
Should I set stdout and stdin to be unbuffered in C?
Related
Exercise 1-9 in The C Programming Language by Denis Ritchie and Brian Kernighan, second edition:
Write a program to copy its input to its output, replacing each string of one or more blanks by a single blank.
Given that I'm using the book as a reference, I know only the C principles which have been discussed in the book up to Exercise 1-9, that is, variable assignments, while- and for-loops, if-statements, symbolic constants, character I/O via getchar() and putchar(), escape sequences and the printf() function. Maybe I'm forgetting something, but that's most of it. (I'm at page 20, where the exercise is at.)
Here's my (not working) code:
#include <stdio.h>
main()
{
int c;
while ((c = getchar()) != EOF) { // As long as EOF is not met, repeat the following…
if(c == ' ') { // If the input character is a blank, proceed (otherwise skip)…
putchar(c); // Output the blank space which was just inputed…
while(c == ' ') { // As long as more spaces keep coming in, don't do anything (proceed when another character comes along)…
;
}
}
else { // When a character other than a blank is inputed, output that character…
putchar(c);
} // Now retest the master while-loop condition (EOF not met) and proceed…
}
}
What I'm getting as a result is a working input-to-output program, that keeps on inputting and stops outputting the moment a blank is typed. (An exception to this is if the blank is removed with a backspace before entering a new line in the console.)
For example, the input abcde\nabcde abcde\nabcde will yield the output abcde, omitting the second and third lines, given that a blank is contained in the former. Here I am obviously using \n to represent an inputted new line (normally using the Enter key).
What have I done wrong, and what could I do to fix this issue? I know there are several working models of this program spread all over the internet, but I'm wondering why this one (which is my creation) in particular doesn't work. Again, do note that my knowledge of C is mostly limited to the first twenty pages of the book whose details are provided below.
Specs:
I'm running Eclipse version 2021-12 (4.22.0) on Debian GNU/Linux 11 (bullseye). I downloaded the pre-compiled Eclipse version from the official Eclipse.org website.
References:
Kernighan, B.W. and Ritchie, D.M. (1988). The C programming language / ANSI C Version. Englewood Cliffs, N.J.: Prentice Hall.
while(c == ' ') is forever loop.
you should try to remember previous character and if prevous character is whitespace and current character is also whitespace, skip it.
#include <stdio.h>
main() {
long nc;
nc = 0;
while (getchar() != -1)
++nc;
printf("%ld\n", nc);
}
Above is my code from K&R C book for example 1.5.2 but I changed the code so getchar() is checking for -1. However when typing in negative one (-1) the code does not stop reading in getchar(). How do I get the code to stop and why is it not stopping?
The getchar() function reads a single byte from stdin, and returns the value of that byte. For example, on an ASCII based system, the byte value 32 represents a space, the value 33 represents an exclamation point (!), the value 34 represents a double quote ("), and so on. In particular, the characters - and 1 (which make up the string "-1") have the byte values 45 and 48 respectively.
The number -1 does not correspond to any actual character, but rather to the special value EOF (an acronym for end of file) that getchar() will return when there are no more bytes to be read from stdin. (Actually, the EOF value is not guaranteed by the C standard to be equal to -1, although on most systems it is. It is guaranteed to be less than zero, though.)
So your loop, as written, will continue to run until there's no more input to be read. If you're running your code from a terminal, that basically means it will keep running until you type Ctrl+D (on Unixish systems) or Ctrl+Z (on Windows). Alternatively, you could run your program with its input coming from a file (e.g. with my_program < some_file.txt), which would cause the loop to run until it has read the entire file byte by byte.
If you instead want to read a number from stdin, and loop until the number equals -1, you should use scanf() instead.
This question already has answers here:
EOF exercise 1-6 K&R The C programming language
(1 answer)
Why does this C program print weird characters in output?
(3 answers)
Why does printf not flush after the call unless a newline is in the format string?
(10 answers)
Closed 5 years ago.
I am a noob teaching myself to program in C using The C Programming Language, Second Edition (by K&R). In Chapter 1 Section 1.5.1 File Copying, the authors touch very briefly on operational precedence when making comparison between values, underscoring the importance of using parenthesis, in this case, to ensure that assignment is made to the variable 'c' before the comparison is evaluated. They make the assertion that:
c = getchar() != EOF
is equivalent to
c = (getchar() != EOF)
Which "has the undesired effect of setting c to 0 or 1, depending on whether or not the call of getchar encountered end of file"
The authors then pose Excercise 1-6 - Verify that the expression getchar () != EOF is 0 or 1
Based on the author's previous assertion, this seemed almost trivial so I created this code:
#include <stdio.h>
main()
{
int c;
while (c = (getchar() != EOF))
putchar(c);
}
Unfortunately, when I run the program, it simply outputs whatever characters I type in the command window rather than the expected string of 1 or 0 if EOF is encountered.
While I am a noob, I think I get the logic that the authors are trying to teach and yet I can not demonstrate this simple task. In this case, should not the variable c take on the value that the comparison expression evaluated to rather than whatever character getchar() happens to fetch, particularly because of the location of the parenthesis? If c is indeed taking on the value of the comparison, putchar() should only output 0 or 1 and yet, as formulated, it outputs what I type in the command window. What am I doing wrong? What do I not understand? Could it be my compiler? I am coding in in Visual Studio 2017 Community edition on Windows 10 on x64 architecture. I have Tiny C Compiler but have not tried executing from command prompt with TCC yet.
When you run the program, the characters that you see doesn't come from your program. It's the console (or terminal)'s echo funcion that shows whatever character you have typed (and you can even erase them before you hit Enter). Your program only outpus characters with ASCII code 0 or 1, both of which are invisible.
If you change putchar(c) to printf("%d", c) you'll be able to see a sequence of 1s. No zero will appear because when c becomes zero, the loop stops and it won't be printed.
Characters '0' and '1' have the ASCII code of 48 and 49, respectively, despite the fact that your terminal may use another encoding. If you want to output a literal number 0, use the character notation. You can also try putchar(48) but don't use this too much (You'll later find out that it's highly discouraged to use magic numbers in your program).
putchar('0');
^ ^
The assertion that
c = getchar() != EOF;
is equivalent to
c = (getchar() != EOF);
is because of operator precedence. The operator != (inequality) has a higher precedence over = (value assignment), so it gets evaluated prior to assignment.
Finally, it's extremely rare for someone to have written that. The correct intention is to write this:
while ( (c = getchar()) != EOF )
The thing is c = (getchar() != EOF) it will get one input character and then it compares. Result will be 1 in case it is not EOF. Then it is assigned. The value of assignment statement is the value that is being assigned. It enters the loop. Prints the character having ascii value 1. But that character is non-printable so you don't see anything.
Once it gets EOF it will break from the loop. So you never get to see anything other than the character which has ascii value of 1.(Even you don't see that also as it is non-printable). These are known as ascii-control characters. (Not belong to the printable class).
Also you said as c=0 or c=1 it should print 0 or 1. Then try this simple code
int c= 68;
putchar(c);
Check the output and you will get the idea what happens when we try to print. It's the character whose ascii code is 68, that is printed, not the value 68.
The right way to do it would be ((c = getchar()) != EOF).
Originally I mentioned that on some machines it prints some funny characters. The representation of the non-printable characters depend on the used charset. It might be some non-standard encoding (non-unicode) which assigns to the ascii code 1 some representation.(breaking the idea of nonprintables)
I was reading K&R book and wanted to test out printf() and putchar() functions in ways that I never tried. I encountered several unexpected events and would like to hear from more experienced programmers why that happens.
char c;
while((c = getchar()) != EOF) {
//put char(c);
printf("%d your character was.\n", c);
}
How would one get EOF (end of file) in the input stream (getchar() or scanf() functions)? Unexpected key that is not recognized by getchar()/scanf() function could produce it?
In my book, it says that c has to be an integer, because it needs to store EOF and the variable has to be big enough to hold any possible char that EOF can hold. This doesn't make sense for me, because EOF is a constant integer with a value of -1, which even char can store. Can anyone clarify what was meant by this?
What happens when I send "hello" or 'hello' to putchar() function? It expects to get an integer, but returns weird output, such as EE or oo, if I send the latter string or char sequence.
Why when I use printf() function that is written above I get two outputs? One is the one I entered and the other one is integer, which in ASCII is end of line. Does it produce the second output, because I press enter, which it assumes to be the second character?
Thanks.
on Linux, you can send it with Ctrl+d
you need an int, otherwise you can't make the difference between EOF and the last possible character (0xFFFF is not the same than 0x00FF)
putchar wants a character, not a string, if you're trying to give it a string, it'll print a part of the string address
you only get one output: the ascii value of the character you entered, the other "input" is what you typed in the terminal
edit - more details about 2
You need an int, because getchar can returns both a character of value -1 (0x00FF) and an integer of value -1 (0xFFFF), they don't have the same meaning: the character of value -1 is a valid character (for instance, it's ÿ in latin-1) while the integer of value -1 is EOF in this context.
Here's a simple program that shows the difference:
#include <stdio.h>
int main(int argc, char ** argv) {
{
char c = 0xFF; /* this is a valid char */
if (c == EOF) printf("wrong end of file detection\n");
}
{
int c = 0xFF; /* this is a valid char */
if (c == EOF) printf("wrong end of file detection\n");
}
}
The first test succeeds because 0xFF == -1 for char, while the second tests fails because 0x00FF != -1 for int.
I hope that makes it a bit clearer.
you must close the input stream to get EOF. Usually with CTRL-D in UNIX, but see you tty config (stty -a)
already answered
same
your tty echoes what you type by default. If you don't want this, set it in noecho mode (stty -echo). Becareful as some shells sets it again to echo. Try with sh. You must be aware taht tty also buffers your inputs until RETURN is types (see stty manual for raw mode if you need).
I'm new to programming and I can't seem to get my head around why the following happens in my code, which is:
#include <stdio.h>
/*copy input to output; 1st version */
main()
{
int c;
c = getchar();
while (c != EOF) {
putchar(c);
c = getchar();
}
}
So after doing some reading, I've gathered the following:
Nothing executes until I hit Enter as getchar() is a holding function.
Before I hit Enter, all my keystrokes are stored in a buffer
When getchar() is called upon, it simply goes looks at the first value in the buffer, becomes that value, and then removes that value from the buffer.
My question is that when I remove the first c = getchar() the resulting piece of code has exactly the same functionality as the original code, albeit before I type anything a smiley face symbol immediately appears on the screen. Why does this happen? Is it because putchar(c) doesn't hold up the code, and tries to display c, which isn't yet defined, hence it outputs some random symbol? I'm using Code::Blocks if that helps.
The function you listed will simply echo back to you every character you type at it. It is true that the I/O is "buffered". It is the keyboard input driver of the operating system that is doing this buffering. While it's buffering keys you press, it echoes each key back at you. When you press a newline the driver passes the buffered characters along to your program and getchar then sees them.
As written, the function should work fine:
c = getchar(); // get (buffer) the first char
while (c != EOF) { // while the user has not typed ^D (EOF)
putchar(c); // put the character retrieved
c = getchar(); // get the next character
}
Because of the keyboard driver buffering, it will only echo back every time you press a newline or you exit with ^D (EOF).
The smiley face is coming from what #YuHao described: you might be missing the first getchar in what you ran, so putchar is echoing junk. Probably a 0, which looks like a smiley on your screen.
If you ommit the first getchar(), the code will look like this:
int c;
while (c != EOF) {
putchar(c);
c = getchar();
}
Here, c is uninitialized, so calling putchar(c) the first time will output a garbage value, that's where you get the smiley face.
"I'm new to programming"
You're not advised to learn programming using C (and the difficulties you're going through are because of the C language). For example, my first computer science classes were in pascal. Other univesities may use scheme or lisp, or even structured natural languages to teach programming. MIT's online classes are given in python.
C is not a language you would want to use in the first months of programming. The specific reason in your case is due to the fact that the language allowed you to use the value of an uninitialized value.
When you declare the integer variable "c", it gets an implicitly reserved space on the program stack, but without have any meaningful value: it's "trash", the value is whatever value was already on memory at that time. The C language requires that the programmer implicitly knows that he needs to assign some value before using a variable. Removing the first getchar results in uses before assignment in the while condition (c != EOF) and putchar(c), both before c has any meaningful value.
Consider the same code rewritten in python:
import sys
c = sys.stdin.read(1)
while c != '':
c = sys.stdin.read(1)
sys.stdout.write(c)
Remove the initial read and you get the following error:
hdante#aielwaste:/tmp$ python3 1.py
Traceback (most recent call last):
File "1.py", line 3, in <module>
while c != '':
NameError: name 'c' is not defined
That's a NameError: you used the value without assigned to it resulted in a language error.
For more information, try an online course, for example:
http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-00-introduction-to-computer-science-and-programming-fall-2008/video-lectures/
About uninitialized values:
http://en.wikipedia.org/wiki/Uninitialized_variable