Are both these two cleaning buffer methods equivalent? - c

I was wondering:
do they do exactly the same thing? calling c = getchar on expression is the same as doing it with a do...while loop?
void clrbuf(void)
{
int c;
while ((c = getchar()) != '\n' && c != EOF);
}
void clrbuf(void)
{
int c;
do c = getchar(); while (c != '\n' && c != EOF);
}
edit: c was once typed char, but folks told me int was the appropriate type for it

For starters the variable c should be declared like
int c;
because if the type char behaves as the type unsigned char then this condition
c != EOF
will be always true.
According to the C Standard (7.21 Input/output <stdio.h>)
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;
So if the type char behaves as the type unsigned char (this depends on compiler options) then the value stored in the variable c after the integer promotion to the type int will be still a non-negative value.
The first while loop
while ((c = getchar()) != '\n' && c != EOF);
may be rewritten using the comma operator like
while ( c = getchar(), c != '\n' && c != EOF );
that is in fact it consists of two parts: the assignment expression c = getchar() and the condition c != '\n' && c != EOF.
As you can see it is equivalent to the do-while statement
do c = getchar(); while (c != '\n' && c != EOF);
However the first while loop
while ((c = getchar()) != '\n' && c != EOF);
is more expressive and clear.

Related

Function of (char)getchar() in C programming

My friend asked me what is (char)getchar() which he found in some online code and I googled and found 0 results of it being used, I thought the regular usage is just ch = getchar(). This is the code he found, Can anyone explain what is this function?
else if (input == 2)
{
if (notes_counter != LIST_SIZE)
{
printf("Enter header: ");
getchar();
char c = (char)getchar();
int tmp_count = 0;
while (c != '\n' && tmp_count < HEADER)
{
note[notes_counter].header[tmp_count++] = c;
c = (char)getchar();
}
note[notes_counter].header[tmp_count] = '\0';
printf("Enter content: ");
c = (char)getchar();
tmp_count = 0;
while (c != '\n' && tmp_count < CONTENT)
{
note[notes_counter].content[tmp_count++] = c;
c = (char)getchar();
}
note[notes_counter].content[tmp_count] = '\0';
printf("\n");
notes_counter++;
}
}
(char)getchar() is a mistake. Never use it.
getchar returns an int that is either an unsigned char value of a character that was read or is the value of EOF, which is negative. If you convert it to char, you lose the distinction between EOF and some character that maps to the same char value.
The result of getchar should always be assigned to an int object, not a char object, so that these values are preserved, and the result should be tested to see if it is EOF before the program assumes a character has been read. Since the program uses c to store the result of getchar, c should be declared as int c, not char c.
It is possible a compiler issued a warning for c = getchar(); because that assignment implicitly converts an int to a char, which can lose information as mentioned above. (This warning is not always issued by a compiler; it may depend on warning switches used.) The correct solution for that warning is to change c to an int, not to insert a cast to char.
About the conversion: The C standard allows char to be either signed or unsigned. If it is unsigned, then (char) getchar() will convert an EOF returned by getchar() to some non-negative value, which will be the same value as one of the character values. If it is signed, then (char) getchar() will convert some of the unsigned char character values to char in an implementation-defined way, and some of those conversions may produce the same value as EOF.
The code is a typical example of incorrect usage of the getchar() function.
getchar(), and more generally getc(fp) and fgetc(fp) return a byte from the stream as a positive value between 0 and UCHAR_MAX or the special negative value EOF upon error or end of file.
Storing this value into a variable of type char loses information. It makes testing for EOF
unreliable if type char is signed: if EOF has the value (-1) it cannot be distinguished from a valid byte value 255, which most likely gets converted to -1 when stored to a char variable on CPUs with 8-bit bytes
impossible on architectures where type char is unsigned by default, on which all char values are different from EOF.
In this program, the variables receiving the getchar() return value should have type int.
Note also that EOF is not tested in the code fragment, causing invalid input strings such as long sequences of ÿÿÿÿÿÿÿÿ at end of file.
Here is a modified version:
else if (input == 2)
{
if (notes_counter != LIST_SIZE)
{
int c;
// consume the rest of the input line left pending by `scanf()`
// this should be performed earlier in the function
while ((c = getchar()) != EOF && c != '\n')
continue;
printf("Enter header: ");
int tmp_count = 0;
while ((c = getchar()) != EOF && c != '\n') {
if (tmp_count + 1 < HEADER)
note[notes_counter].header[tmp_count++] = c;
}
note[notes_counter].header[tmp_count] = '\0';
printf("Enter content: ");
tmp_count = 0;
while ((c = getchar()) != EOF && c != '\n')
if (tmp_count + 1 < CONTENT)
note[notes_counter].content[tmp_count++] = c;
}
note[notes_counter].content[tmp_count] = '\0';
printf("\n");
notes_counter++;
}
}

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);//
}
}

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.

Exercise 1-6: (page 17 K&R) - getchar() question

When I run the program below, output give second 1. I debug the program, but I couldn't understand why compiler writing second 1 anytime?
output like this.
#include <stdio.h>
main()
{
int c;
while (c = getchar() != EOF)
printf("%d\n", c);
printf("%d - at EOF\n", c);
}
The condition in the while statement
while (c = getchar() != EOF)
is equivalent to
while (c = ( getchar() != EOF) )
due to the operator precedence. And this logical expression getchar() != EOF always yields 1 if the input was not interrupted.
You need to write
while ( ( c = getchar() ) != EOF)
The Enter key you press to "send" the input from the terminal to the program is added in the input buffer as a newline '\n', which will be read in the second iteration of the loop.

How can I get the numbers from tupple?

I want to get an input from the user like (4,5).But I just want to get the integer values.(4 and 5) I wrote a code for this.But it did not work.How can I fix the problem.
int x, y;
int c;
c = getchar();
while (c != EOF) {
while (c != '(' && c != EOF) {
c = getchar();
}
while (c != ',' && c != EOF) {
c = getchar();
}
x = c;
while (c != ',' && c != EOF) {
c = getchar();
}
while (c != ')' && c != EOF) {
c = getchar();
}
y = c;
}
I get input(1,4). outputs is x= 44 and y= 45 ?
After you find the opening parenthesis, read characters while they are digits (see e.g. isdigit), and create your number.
When the character is not a digit, make sure it's a comma. If it is you read the next number the same as above. Finally make sure you got the closing parenthesis.
The above assumes that there are no whitespace between the parentheses and the numbers, or between the numbers or the comma. Those can be handled by looping and isspace.
As for converting digits to numbers, assuming your system is using ASCII encoding (which is standard on modern PC-like systems) then it's easy since you just subtract '0' from the character to get the digit (see the linked ASCII table to help you understand why). Store the value in a variable, initialized to zero, and multiply by ten as needed.
Depending on the parser you're writing, you could do the handling and recognition of tuples in the parser instead of the lexer. That would make it more flexible.
follow your code flow x value will be character comma.
int c ,x ,y;
c = getchar();
while (c != EOF) {
while (c != '(' && c != EOF) {
c = getchar();
}
c = getchar();
x = c;
while (c != ',' && c != EOF) {
c = getchar();
}
/*x = c;
while (c != ',' && c != EOF) {
c = getchar();
}
*/
c = getchar();
y = c;
while (c != ')' && c != EOF) {
c = getchar();
}
//y = c;
printf("x = %c ,y = %c ",x,y);
}

Resources