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.
Related
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++;
}
}
Code:
int main(void) {
int c;
c = getchar();
while (c != EOF) {
putchar(c);
c = getchar();
printf("%d", c);
}
}
I enter a character and that character is returned with putchar(c), however, if I print that character I get a code back? example:
0 = 48010
1 = 49110
2 = 50210
etc...
what are these numbers? is this where the character is stored in memory or something?
cheers
So I believe I figured out the problem by introducing newlines
int main(void) {
int c;
c = getchar();
while (c != EOF) {
putchar(c);
printf("\n");
c = getchar();
printf("%d\n", c);
}
}
When I enter 1 this returns the following in the terminal window.
49
1
10
What's happening is I'm returning the ASII character code for 1 - > 49
returning the value I entered with getchar()
and returning 10 which is the linefeed value i.e. the enter command.
Right? without the newlines it was just concatenating them all, making it confusing.
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)
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.
Hi I'm relatively new to programming so please bear with me.
I would like to make a program that takes the input bcdefghijklmnopqrstuvwxy and outputs
else if (c == 'x')
++nx;
where x is a letter of the input, and where the output is repeated for each letter of the input.
This is what I have written so far:
#include <stdio.h>
main() {
int c;
while((c = getchar()) != EOF) {
printf("else if (c == '%d')\n", c);
printf("\t++n%d;\n", c);
}
return 0;
}
Instead of returning the output I want, the output is
else if (c == '98')
++n98;
else if (c == '99')
++n99;
else if (c == '100')
++n100;
else if (c == '101')
++n101;
else if (c == '102')
++n102;
...
Why is c not working as a variable?
Thanks so much for your help!
You want c == '%c' to compare by character or c == %d (without the single quotes) to compare by ordinal value, but you should really learn to use arrays. It looks like you are trying to code something the hard way, and use a code generator to save you some typing. Instead:
int n[256] = {0}; /* storage for counters, initialized to zero */
and:
n[c]++; // increment the counter for character c;
You're code will be much shorter.
When writing in C and printing a string pointed by format to stdout you'll need to make sure you're using the right format specifiers. This will ensure that your argument is formatted correctly and inserted into the resulting string as you would expect.
In your case, you need to use %c. However, you have %d currently, which is the equivalent to %i for integers. You can google more on format specifiers to learn more about other options as well.
Here's an interesting read on the subject:
http://www.codingunit.com/printf-format-specifiers-format-conversions-and-formatted-output
You used %d in your printf but %d if for integers. You want to print a char so it should be %c.
Replace %d by %c
More on this link: http://www.lix.polytechnique.fr/~liberti/public/computing/prog/c/C/FUNCTIONS/format.html
Try:
#include <stdio.h>
main() {
char c;
while((c = getchar()) != EOF) {
printf("else if (c == '%c')\n", c);
printf("\t++n%c;\n", c);
}
return 0;
}
what you want is characters not ints
Try using
printf("else if (c == '%c')\n", c);
printf("\t++n%c;\n", c);
See printf specifiers
The %d specifier is for intergers