C getchar() misunderstanding - c

Can someone explain me the code ?? Wouldn't d be always equal to c ? I guess I don't really get this getchar() function.Why isn't d always equal to `c ?
#include<stdio.h>
void test(int c);
int main(void) {
int c;
while ((c = getchar()) != EOF) {
test(c);
}
return 0;
}
void test(int c) {
int d;
if (c == '/') {
d = getchar();
printf("%c", d);
}
}
Input:
/*
Output:
*

No, not really. As mentioned in C11, chapter ยง7.21.7.6, The getchar function, (emphasis mine)
The getchar function returns the next character from the input stream pointed to by
stdin. [...]
So, each call to getchar() will give you the next character input present in the input stream. So, when c == '/' condition is met, it will read the next entry and store into d, it need not be the same as c, anyway.

Related

dev c++, c programme, every character is displaced by a square

#include<stdio.h>
int main()
{
char c;
while((c=getchar()!=EOF))
{
putchar(c);//
}
}
Every character of the output is displaced by '' these sorts of things.
enter image description here
Your parentheses are wrong so c gets assigned the value of the condition, which is 0 or 1 (false or true).
What you have now is the same as c = (getchar() != EOF) because of operator precedence.
Also, use the correct type for c, which is int:
#include<stdio.h>
int main()
{
int c;
while( (c = getchar()) != EOF )
{
putchar(c);//
}
}

Copying the input from `getchar()` to another variable

In the following code example from K&R's book, if I replace putchar(c) with printf("%c", c) the code works the same. But if I replace it with printf("%d", c) it gives gibberish output.
#include <stdio.h>
int main() {
int c;
c = getchar();
while (c != EOF) {
putchar(c);
c = getchar();
}
}
From here, I learned that the getchar() converts the stdin to an 8-bit character whose value ranges from 0 to 255.
Now I want to print the value of c using putchar(c) in one line and printf("%d", c) in another line. So I wrote the following code:
#include <stdio.h>
int main() {
int c, b;
c = getchar();
b = c;
while (c != EOF && c != 10) {
printf("%c",c);
c = getchar();
}
printf("\n");
while (b != EOF && b != 10) {
printf("%d\t",b);
b = getchar();
}
}
I used the condition c != 10 as the newline character is read as 10 by getchar(). I expected the code to work as
$ ./a.out
783
783
55 56 51
but the program terminates as
$ ./a.out
783
783
55
I understand that getchar() takes input from stdin and the variable b is not stdin. So how should I copy the variable c to b so that my program works as I expect it to?
The problem is that your code does not (and cannot, as it stands) 'remember' the inputs you gave in the first loop. So, after you have finished that loop, your second loop is wanting to read in the characters for b (after it has output the first value, which is remembered from the earlier b = c line).
So, after outputting 55 (the integer value of the character 7), it is waiting for further input.
Probably the easiest way to get the output that you're looking for is to have an array of input characters. Then, you can output the %c values as you read them (as before), then re-run the outputs using the %d format in a subsequent for loop.
Here is a demonstration that does what I think you're after:
#include <stdio.h>
#define MAXINS 20 // Set to the maximum number of input characters you want to allow
int main()
{
int c[MAXINS];
int i = 0, n = 0;
c[0] = getchar();
while (i < MAXINS && c[i] != EOF && c[i] != 10) {
printf("%c", c[i]);
c[++i] = getchar();
++n;
}
printf("\n");
for (i = 0; i < n; ++i) {
printf("%d\t", (int)(c[i]));
}
return 0;
}
Feel free to ask for further clarification and/or explanation.
EDIT: On the point in the your first paragraph, "But if I replace it with printf("%d", c) it gives gibberish output." Well, when I try the following code and give 783 and then hit return (which generates a newline) I get the expected 55565110 as the output:
int main()
{
int c;
c = getchar();
while (c != EOF) {
printf("%d", c);
c = getchar();
}
return 0;
}
This may look like gibberish, but it's just the same output as you 'expect' in your later code, but without the spaces and with the addition of the 10 for the newline.
You need to have every character stored, because once you read a char from stdin, it is not present in stdin anymore.
Since you want the newline character in the end as a part of the input, you should use fgets to take the input.
Say you are taking an input that could have a maximum of 100 characters.
#include <stdio.h>
int main(void) {
char c[100]; // A char array
fgets(c,100,stdin);
int x=0;
while (c[x] != 10 && c[x] != EOF)
printf("%c",c[x++]);
printf("\n");
x = 0;
while (c[x] != 10 && c[x] != EOF) // You can simply compare it with the newline character too.
printf("%d ",c[x++]);
printf("\n");
return 0;
}
There are many ways to do this. You can also read stdin character-by-character ans store it in an array. However, since you need to display the ASCII values of the characters in another line after displaying the characters themselves, you will have to store them in an array.
You are copying only the first input, to copy the whole string you need to store each input in a buffer and check if the string doesn't overflow that buffer on each iteration:
int main(void)
{
enum {size = 256};
char buffer[size];
size_t count = 0;
int c;
while ((c = getchar()) && (c != '\n') && (c != EOF))
{
printf("%c", c);
if (count < size)
{
buffer[count++] = (char)c;
}
}
printf("\n");
for (size_t iter = 0; iter < count; iter++)
{
printf("%d\t", buffer[iter]);
}
printf("\n");
}
If you don't want to limit the buffer to an arbitrary size then you need to change your approach to use dynamic memory (realloc or a linked list)

not able to understand the role of getchar and putchar here

#include <stdio.h>
#include <stdlib.h>
int main()
{
int c;
c = getchar();
while (c != EOF) {
putchar(c);
}
return 0;
}
when I compile and give input ABC and then press enter, the never ending loop starts like AAAAAAAAA....
And now look at this code below
#include <stdio.h>
#include <stdlib.h>
int main()
{
int c;
c = getchar();
while (c != EOF) {
putchar(c);
c = getchar (); // added this single line
}
return 0;
}
In this program, when I input ABC, the output is ABC.
Can anyone please explain why it is not showing just a single A as output?
Look at the below code you mentioned
int main(void){
int c;
c = getchar();
while (c != EOF) {
putchar(c);
}
return 0;
}
When c = getchar(); executes & if you provided input as ABC at runtime & press ENTER(\n), that time c holds first character A.
Next come to loop, your condition is c!=EOF i.e A!=EOF which always true & it will print A infinitely because you are not asking second time input so c holds A.
correct version of above code is
int main(void){
int c;
while ( (c = getchar())!=EOF) { /* to stop press ctrl+d */
putchar(c);
}
return 0;
}
case 2 :- Now looks at second code
int main(void){
int c;
c = getchar();
while (c != EOF) { /*condition is true */
putchar(c);
c = getchar ();/*After printing ABC, it will wait for second input like DEF, unlike case-1 */
}
return 0;
}
Can anyone please explain why it is not showing just a single A as output ? Why it should prints only A, it prints whatever input you given like ABC & so on. Just note that getchar() works with buffered input i.e when you press ENTER getchar() will read upto that & when there is nothing left to read getchar() returns EOF.

Understanding K&R's getint() (Chapter 5: Pointers & Arrays, Exercise 1)?

I'm a novice programmer who's self-studying C through K&R. I don't understand the design of their function getint(), which converts a string of digits into the integer it represents. I'll ask my question then post the code below.
If getch() returns a non-digit character that's not a '-' or '+', it pushes this non-digit character back onto the input with ungetch(), and returns 0. So, if getint() is called again, getch() will just return that same non-digit character that was pushed back, so ungetch() will push it back again, etc. The way I understand it (which could be wrong), the function breaks completely if it's passed any non-digit character.
The exercise doesn't have you fix this. It asks to fix the fact that a '-' or '+' followed by a non-digit is a valid representation of 0.
What exactly am I missing here? Did they design getint() to make an infinite loop if the input is anything other than 0-9? Why?
Here's their code for getint() [edit] with main calling getint():
int getint(int *);
int main()
{
int n, array[BUFSIZE];
for (n = 0; n < BUFSIZE && getint(&array[n]) != EOF; n++)
;
return 0;
}
int getch(void);
void ungetch(int);
int getint(int *pn)
{
int c, sign;
while (isspace(c = getch())
;
if (!isdigit(c) && c != EOF && c != '+' && c != '-') {
ungetch(c); //this is what i don't understand
return 0;
}
sign = (c == '-') ? -1 : 1;
if (c == '-' || c == '+')
c = getch();
for (*pn = 0; isdigit(c); c = getch())
*pn = 10 * *pn + (c - '0');
*pn *= sign;
if (c != EOF)
ungetch(c);
return c;
}
int buf[BUFSIZE];
int bufp = 0;
int getch(void)
{
return (bufp > 0) ? buf[--bufp] : getchar();
}
void ungetch(int c)
{
if (bufp >= BUFSIZE)
printf("ungetch: can't push character\n");
else
buf[bufp++] = c;
}
As it is currently written, getint() function is trying to read an integer from user input and puts it into *pn.
If user inputs a positive or negative number(with a sign or without it), *pn gets updated to that number and getint() returns some positive number (the next character after the number).
If user inputs a non valid number, *pn is not updated and getint() returns 0 (meaning it failed).
the function breaks completely if it's passed any non-digit character.
That's right. All subsequent calls to getint() will fail as the last character was passed to ungetch(). What you understand is correct.
But this is how getint() is supposed to handle garbage input. It'll simply reject it and return 0 (meaning it failed). It is not the responsibility of getint() to take care of non-integer input and prepare fresh input for next read. It is not a bug.
The only bug is that a '-' or '+' followed by a non-digit is currently being considered as a valid representation of 0. Which is left to reader as an exercise.
If user inputs EOF, *pn is not updated (multiplied by 1) and getint() returns EOF.
The reasoning is similar to scanf not consuming characters that don't match the conversion specifier - you don't want to consume something that isn't part of a valid integer, but may be part of a valid string or other type of input. getint has no way of knowing whether the input it rejects is part of an otherwise valid non-numeric input, so it has to leave the input stream the same way it found it.

Reading chars in C

I wrote the following program to understand the behavior of EOF:
#include<stdio.h>
int main ()
char c = 0;
printf("Enter some chars, EOF stops printing:");
while ((c == getc(stdin)) != EOF)
printf("c = %c, (int) c = %d\n", c, (int) c);
return 0;
}
However, if I input something such as abcd I get this output:
c = a, (int) c = 97
c = a, (int) c = 97
c = a, (int) c = 97
You've got a == instead of a = so you never store whatever getc returns:
while ((c == getc(stdin)) != EOF) {
^^
And of course c should be int, not char.
You must read the documentation better; getc() returns int, because EOF doesn't fit in a char.
Also, you're using both scanf() and getc(), which will make things confusing due to the input stream buffering.
Try something like this:
#include <stdio.h>
int main()
int c = 0;
printf("Enter some chars, EOF stops printing:");
while ((c = getc(stdin)) != EOF) {
printf("c = %c, (int) c = %d\n", c, c);
}
return 0;
}
I also added the missing } in your code, and removed the cast of c in the call to printf(), that's not needed now that c is int. This is the proper type for the %c formatting specifier too, by the way.

Resources