Reputation: 25
I want to write a program that counts the frequency of all characters in stdin. My code:
#include <stdio.h>
#define MAX 1024
int main()
{
char c1, c2;
int count[MAX], i = 0, unique = 1;
char arr[MAX];
c1 = fgetc(stdin);
while(c1 != EOF)
{
unsigned counter = 0;
for(int j = 0; j < i; j++)
{
if(c1 == arr[j])
{
unique = 0;
break;
}
}
if(unique)
arr[i] = c1;
ungetc(c1, stdin);
c2 = fgetc(stdin); // a
while (c2 != EOF)
{
if(arr[i] == c2)
{
counter++; // 2
c2 = fgetc(stdin); //\n
}
else if(arr[i] != c2 && c2 != EOF)
{
//ungetc(c2, stdin);
c2 = fgetc(stdin); // a EOF
}
}
count[i] = counter;
rewind(stdin);
printf("%c: %d\n", arr[i], count[i]);
c1 = fgetc(stdin); // a
i++;
}
return 0;
}
For the input: anna
the output is: a: 2
, so it counts all appearances for the 1st character but then EOF is reached, and I can't count any of the other characters. rewind(stdin)
doesn't seem the work. What can I do?
Upvotes: 1
Views: 454
Reputation: 168986
You can't rewind a piped stream (such as stdin when it is e.g. redirected into your program or being entered on the keyboard) since there is no "tape of characters" to rewind, it's just a stream with no "memory" of what was entered before.
As elucidated in the comments, if you do redirect in a file (./myapp < data.txt
), it can be rewound just fine.
However, you don't need to rewind the file to count the characters in it. As I commented,
Keep track of all characters (assuming ASCII) in an array of 256 unsigned ints, read through the stream, print them at the end.
#include <stdio.h>
int main() {
int c;
unsigned int counts[256] = {0};
while ((c = fgetc(stdin)) != EOF) {
counts[c]++;
}
for (int i = 0; i < 256; i++) {
if (counts[i]) {
printf("%c: %d\n", i, counts[i]);
}
}
return 0;
}
As other commenters mention, you also need to use an int
, not a char
, for the retval of fgetc()
, since EOF is -1.
Upvotes: 2