Count all character occurrences in a text file - c

The following code snippet is intended to count all the symbols met in a file after text is entered, next step is counting the occurrences of all characters (For instance 'a' met 3 times, 'b' 0 times etc.). However when I compile the loop goes infinite and the counting is always 0. My question is if it could be fixed or rewritten in another way.
char type, c, text[100]; counts[100];
int count=0, i;
while((type=getchar())!=EOF) {
fputc(type, f); count++;
}
printf("Symbols found: %d", count-1);
rewind(f);
while(fscanf(f, "%s", &text)) {
for (i = 0; i < strlen(text); i++) {
counts[(text[i])]++;
printf("The %d. character has %d occurrences.\n", i, counts[i]);
}
}

You can build your histogram as you read the input. The return value from getchar() is an int, not a char, since it has to represent EOF in addition to the 256 char values. Once the histogram has been built, you can iterate over the buckets and print them. Here, I have assumed that all 256 char values are possible, and included code to display unprintable characters in hex notation.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main(int argc, char **argv)
{
int c;
int i;
int histogram[256];
int total;
memset(histogram, 0, sizeof(histogram));
total = 0;
while ((c = getchar()) != EOF) {
histogram[c]++;
total++;
}
printf("Symbols found: %d\n", total);
for (i = 0; i < 256; i++) {
if (histogram[i]) {
char repr[5];
sprintf(repr, isprint(i) ? "%c" : "\\x%02x", i);
printf("The '%s'. character has %d occurrences.\n", repr, histogram[i]);
}
}
return 0;
}

Your for loop scans the string with variable i being an index to the character tested, but your printf says i is a symbol accounted.
You should separate counting and printing results:
char * ptr;
while(fscanf(f, "%s", text))
for (ptr = text; * ptr != 0; ptr++)
counts[ (unsigned char)*ptr ]++;
for( i = 0; i < 256; i++)
printf("The %d. character has %d occurrences.\n", i, counts[i]);
Don't forget to declare count[ 256] and note that scanf gets text, not `&text~as a destination.

Related

Why is my program returning the wrong value?

I'm trying to write a program that takes a string as an input, and returns any characters in the string which occur more than once, along with how frequently they occur. What I haven't been able to figure out is finding a way to get the program to return "No duplicates found" for strings with no repeating characters.
# include <stdio.h>
# include <stdlib.h>
#include <ctype.h>
# define NO_OF_CHARS 256
char fillCharCounts (unsigned char *str, int *count) {
int i;
for (i = 0; * (str + i); i++)
count[* (str + i)]++;
return 0;
}
void printDups (unsigned char *str) {
int *count = (int *) calloc (NO_OF_CHARS, sizeof (int));
fillCharCounts (str, count);
int i;
for (i = 0; i < NO_OF_CHARS; i++)
if (count[i] > 1)
printf ("\nDuplicate letter: %c, Occurrences: %d", i, count[i]);
/* area of concern */
if (count[i] < 1)
printf ("\nNo duplicates found\n");
exit (0);
printf ("\n");
free (count);
}
int main() {
unsigned char str[15] = "";
printf ("Enter a word>");
scanf ("%s", str);
printDups (str);
getchar();
return 0;
}
The program returns characters that occur more than once along with their frequency, but it always returns "No duplicates found" along with this. How can i fix it so it only returns "No duplicates found" for strings with no repeating characters?
You need to use a flag/counter say dupe_chars to track if one or more duplicate characters were found.
int dupe_chars = 0; // an integer flag/counter
for (int i = 0; i < NO_OF_CHARS; i++)
if (count[i] > 1) {
printf ("\nLetter: %c, Occurrences: %d", i, count[i]);
++dupe_chars; //counting duplicate letters
}
/* area of concern */
if (0 != dupe_chars)
printf ("\nDuplicates of %d chars were found\n", dupe_chars);
else
printf ("\nNo duplicates were found\n");
//exit (0); // not necessary

Error: value computed is not used [-Werror=unused-value]

Ive written this code to try and read if there are any duplicate letters in a word, but I keep coming across this error:
Error: value computed is not used [-Werror=unused-value]
The line in question is:
arr[(int)(str[i])++];
The whole code is:
#include<stdio.h>
#include<string.h>
int main()
{
char str[30];
printf("Enter your String:");
scanf("%[^\n]",str);
int i;
int arr[256]={0};
for(i=0;i<strlen(str);i++)
{
if(str[i]==' '){
continue;
arr[(int)(str[i])++];
}
}
printf("Repeated character in a string are:\n");
for(i=0;i<256;i++)
{
if(arr[i]>1)
{
printf("%c occurs %d times\n",(char)(i),arr[i]);
}}
return 0;
}
Here is the error message from the console:
https://i.stack.imgur.com/GpMOW.png
Any help is appreciated :)
I've made some changes to the code, shown in comment.
#include <stdio.h>
#include <string.h>
int main()
{
char str[30];
printf("Enter your String:");
scanf("%29[^\n]", str); // limit the input length
int i;
int arr[256] = { 0 };
for(i = 0; i < strlen(str); i++)
{
if(str[i] == ' '){
continue;
}
// this line was repositioned so that it can execute
// char can be signed, so don't index by a negative value
// the post-increment should apply to the `arr[]` array element
arr[ (unsigned char)str[i] ]++;
}
printf("Repeated character in a string are:\n");
for(i = 0; i < 256; i++)
{
if(arr[i] > 0) // inform *any* usage
{
// (char)i gets promoted to int anyway
printf("%c occurs %d times\n", i, arr[i]);
}
}
return 0;
}
Session:
Enter your String:one two
Repeated character in a string are:
e occurs 1 times
n occurs 1 times
o occurs 2 times
t occurs 1 times
w occurs 1 times

Maximum number of Characters in a character array

//Program to find max occurring character in string
#include<stdio.h>
#include<conio.h>
#define MAX_SIZE 100 // Maximum string size, change to make string smaller or larger
#define MAX_CHARS 255 // Maximum characters allowed for characters
void main()
{
char str[MAX_SIZE]; //store the string
int freq[MAX_CHARS]; // store frequency of each character
int i, max; // i is for loop max to store frequency
int ascii; //stores ascii value convertd from each char
char ch; //for choice
do{
clrscr();
i=0;
printf("\nEnter any string: ");
gets(str);
// Initializes frequency of all characters to 0
for(i=0; i<MAX_CHARS; i++)
{
freq[i] = 0;
}
// Finds occurance/frequency of each characters
i=0;
while(str[i] != '\0')
{
ascii = (int)str[i];
freq[ascii] += 1; //string's element is casted to int to store its ascii value for further comparision
i++;
}
// Finds maximum frequency of character
max = 0;
for(i=0; i<MAX_CHARS; i++)
{
if(freq[i] > freq[max])
max = i; //to print no. of times
}
printf("\nMaximum occurring character is '%c' = %d times.", max, freq[max]);
printf("\n Want to find again??(y/n):");
scanf("%c",&ch);
}while(ch=='Y'||ch=='y');
}
When I give it the input: "aaaaeeee", the output is "a" occurring 4 times, but "e" occurs 4 times too. I know this is sorted by ascii values and thats why it gives "a" as output, but what can I do in this program that the output gives both "a" and "e" as output when a case like this occurs?
Add max calculation ahead
i = 0;
max = 0;
while(str[i] != '\0')
{
ascii = (int)str[i];
freq[ascii] += 1;
if (freq[ascii] > max) max = freq[ascii]; // <==== here
i++;
}
Note that this is the max number of the same character you might have.
Then display all chars which maximum is equal to max
for(i=0; i<MAX_CHARS; i++)
{
if(freq[i] == max) printf("Character %c is at max %d\n", i, max);
}
To fix the endless loop, before the while add char c ; while ((c = getchar()) != EOF && c != '\n');
scanf("%c",&ch);
char c;
while ((c = getchar()) != EOF && c != '\n'); // <== note the ';'
} while(ch=='Y'||ch=='y');
Note that you shouldn't use gets, reason is explained here.
Whole code:
void main()
{
char str[MAX_SIZE]; //store the string
int freq[MAX_CHARS]; // store frequency of each character
int i, max; // i is for loop max to store frequency
int ascii; //stores ascii value convertd from each char
char ch; //for choice
do {
printf("\nEnter any string: ");
gets(str);
// Initializes frequency of all characters to 0
for(i=0; i<MAX_CHARS; i++)
{
freq[i] = 0;
}
// Finds occurance/frequency of each characters
for(i=0,max=0 ; str[i] != '\0' ; i++)
{
ascii = (int)str[i];
freq[ascii] += 1; //string's element is casted to int to store its ascii value for further comparision
if (freq[ascii] > max) max = freq[ascii];
}
for(i=0; i<MAX_CHARS; i++)
{
if(freq[i] == max) printf("Character %c is at max %d\n", i, max);
}
printf("\n Want to find again??(y/n):");
scanf("%c",&ch);
char c;
while ((c = getchar()) != EOF && c != '\n');
}while(ch=='Y'||ch=='y');
}
Above this line
printf("\nMaximum occurring character is '%c' = %d times.", max, freq[max]);
Delete it and add this code
for(i=0;i<MAX_CHARS;i++)
{
if(freq[i]==freq[max])
{
printf("\nMaximum occurring character is '%c' = %d times.", i, freq[i]);
}
}

Compare character with array

I want to make a program that counts the vowels in a sentence entered by the user.
For that compare a character that capitalizes with the vowel arrangement, but although they do not pulls error, do not type the correct output.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <conio.h>
//Program EJER004
int main(){
char vowels[5] = {'A','E','I','O','U'};
int count;
char letter;
count = 0;
printf("Enter a phrase, ending with a point\n");
do{
letter=getchar();
if (toupper(letter) == vowels[5]) /*attempt ask if is a vowel the letter introduced*/
count++;
}while (letter != '.');
printf("\n");
printf("\n");
printf("The number of vowels in the phrase introduced is% d", count);
getch();
return 0;
}
It think the problem is the comparison toupper(letter) == vowels[5]? vowels[5] is always out of array, but other vowels aren't checked.
You would need to add a loop like:
char upr=toupper(letter);
for(int i=0; i<5; i++)
if(vowels[i]==c)
{ cont++;
break;
}
You should write a small function for this comparison
int checkforVowels(char tobechecked)
{
//this only get vowels in CAPSLOCK tho... so dont forget toupper
char vowels[5] = {'A','E','I','O','U'};
int hasvowel = 0;
for(int i = 0; i < 5; i++)
{
if(tobechecked == vowels[i])
{
hasvowel = 1;
break;
}
}
return hasvowel;
}
so you can have it like that
if(checkforVowels(toupper(letter))
HTH

How do I save integers read by getchar() to an array?

I am trying to make a program that will use getchar() to read three integers and store it in an array but something is wrong in my code.
#include <stdio.h>
int main( )
{
printf("Please enter three digit number 100 to 999: ");
int numEntered[2];
numEntered = getchar();
for (int i = 0; i<3; i++) {
printf("%d", numEntered[i])
}
}
Try this:
#include <stdio.h>
int main(){
printf("Please enter three digit number 100 to 999: ");
int numEntered[3];
for (int i = 0; i<3; i++){
scanf("%d", &numEntered[i]);
printf("%d", numEntered[i]);
}
return 0;
}
you need to read a value inside the for loop! Second thing, by reading with getchar(), you are getting the ascii value of the character, so.. if you read "1" and print with %d, you actually printing 49!
See the ascii table here: http://www.asciitable.com/index/asciifull.gif
let's try and and think about the problem here:
do you want to read and store an integer value? if yes -> use scanf
do you want to read a number digit by digit? if yes -> use getchar
do you want to make sure what you read has exactly 3 digits? if yes...what do you do when it does not?
if reading digit by digit, make sure you are reading numbers; getchar reads characters -> use atoi funtion or check ascii value;
Putting it all together(some assumptions were made):
int main()
{
char digits[3]; // don't use ints to store chars...
printf("enter the 3 digit number - 100 to 999: ");
for (int i=0;i<3;i++) // only the first 3 chars are read
{
char c = getchar();
if (char < '0') || (char > '9')
{
printf("invalid digit!");
exit(0);
}
digits[i] = c;
}
printf("the number entered is: %c%c%c", digits[0],digits[1],digits[2]);
}
You don't use getchar to get integer values.
Use scanf() instead.
Try this:
#include <stdio.h>
int main( )
{
printf("Please enter three digit number 100 to 999: ");
int numEntered[3];
for (int i = 0; i<3; i++){
scanf("%d",&a[i]);
printf("%d", numEntered[i]);
}
}
numEntered = getchar();
(1) It can not be assigned to the array itself.
(2) getchar() reads one character.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main(void){
char digits[4] = {0};//4: 3 character + NUL character
int ch, value;
do {
printf("Please enter three digit number 100 to 999: ");
for(int i = 0; i < 3 && (ch = getchar()) != '\n' && ch != EOF; ++i){
digits[i] = ch;
}
if(ch != '\n')
while((ch = getchar()) != '\n')
if(!isspace(ch))//invalid input
*digits = 0;
value = atoi(digits);
} while(value < 100 || 999 < value);
char *rotate_left(char digits[4]);
printf("%d\n", value);
printf("%d\n", atoi(rotate_left(digits)));
printf("%d\n", atoi(rotate_left(digits)));
return 0;
}
char *rotate_left(char digits[4]){
char temp = digits[0];
digits[0] = digits[1];
digits[1] = digits[2];
digits[2] = temp;
return digits;
}

Resources