What am I supposed to do in order to print only the duplicated words in a file. I'm a beginner in C.
Here's my code:
#include <stdio.h>
#define max 100
main(){
FILE *fpointer;
char ch[max],str[max][max];
int i = 0,j = 0,count = 0;
int a,b;
fpointer = fopen("1.txt","r");
if(fpointer == NULL){
printf("Error!");
return 0;
}
while(fscanf(fpointer,"%s",ch)!=EOF){
strcat(str[i++],ch);
strcat(str[i++]," ");
count++;
}
for(a=0;a<count*2;a=a+2){
for(b=0;b<count*2;b=b+2){
if(strcmp(str[a],str[b])==0){
printf("%s\n",str[b]);
}
}
}
fclose(fpointer);
return 0;
}
An example of input is "shine little star shine bright in the dark star"
and the output of this program is "shine shine little star star shine shine bright in the dark star star". Please help me to print
only duplicate words. Tnx
In your inner loop, instead of starting at the beginning of the list, start one element after the current one. That way you're not comparing an element against itself or comparing any two elements twice.
for(a=0;a<count*2;a=a+2){
for(b=a+2;b<count*2;b=b+2){ // b=a+2 instead of b=0
if(strcmp(str[a],str[b])==0){
printf("%s\n",str[b]);
}
}
}
Output:
shine
star
Since you wrote duplicate words, i am guessing the words in the file will be repeated twice only.
So you second nested for loop is starting from the beginning every time, and thats where the problem is. You have to make sure that the word already checked is not iterated over again. For that you can change your second for loop a little
for(a=0;a<count*2;a=a+2){
for(b=a+2;b<count*2;b=b+2){ //notice b=a+2
if(strcmp(str[a],str[b])==0){
printf("%s\n",str[b]);
}
}
}
Note
For cases when the words are repeating more then twice, my suggestion would be to use some hashing technique to store if a word has already occurred or not. And then compare and print accordingly.
You have a couple of problems here.
Go through and write some comments. For example, put these where they belong:
// Open the file
// Read in the strings
// Compare the strings
If you do this you will notice you have some problems. For instance, what is this line for?
strcat(str[i++]," ");
It's not reading in a string. So what is it doing?
In your final loop, you want to compare each string with all the others. So obviously, you start with the first string, and you compare it to all the others:
for (a=1; a<count; a++)
if(strcmp(str[0],str[a])==0)
{
printf("%s\n",str[0]);
break;
}
Now we can compare the first string with each following string and print it out if it is duplicated. The "break" is there so we only print it once.
But this only compares the first string with the others. How do we compare all of them? Another loop, of course.
// Compare each string against all the ones after it
for (target=0; target<count; target++)
for (a=target+1; a<count; a++)
// If the strings match AND they are not both null
// (why print out copies of null strings? - nobody wants that)
if(strcmp(str[target],str[a])==0) && strlen(str[a])
{
// Print it
printf("%s\n",str[target]);
// Why is this here?
strcpy(str[a],"");
for (copies=a+1; copies<count; copies++)
if(strcmp(str[copies],str[target])==0)
strcpy(str[copies],"");
// We got a match, stop checking for this string
break;
}
See how we've got one big loop that steps through each string, and a smaller loop that steps through all the remaining strings (no point in stepping through the ones we already looked at).
Now a question for you: why is "strcpy(str[a],"") and the next for loop in there? What purpose do they serve?
This is one way to do it. Please enable warnings - you left out a library header. I've also checked array limits. You need to find a better way to limit the string input too, than just guess a large array size.
#include <stdio.h>
#include <stdlib.h>
#include <string.h> // included header
#define MAX 100
int main(void){ // correct function
FILE *fpointer;
int reported [MAX];
char ch[MAX], str[MAX][MAX];
int index = 0, a;
fpointer = fopen("1.txt","r");
if(fpointer == NULL){
printf("Error!");
return 0;
}
while(fscanf(fpointer,"%s",ch) == 1){ // testing for 1 item read
for(a=0; a<index; a++){
if(strcmp(ch, str[a])==0){
if (reported[a] == 0) // don't report twice
printf("%s ",ch);
reported[a]++;
break;
}
}
if(a >= index) { // check if loop completed
if (index >= MAX) { // check if array is full
printf("\nToo many words read\n");
exit(1);
}
strcpy(str[index], ch); // word was not found
reported[index] = 0;
index++; // keep tabs on array length
}
}
printf("\n",ch);
fclose(fpointer);
return 0;
}
Program output:
shine star
One issue is that you are storing every word, regardless of whether it has already been seen:
while(fscanf(fpointer,"%s",ch)!=EOF){
strcat(str[i++],ch);
strcat(str[i++]," "); // ??? what is this for
count++;
}
Ideally, you'd only like to store each word once, and maintain a count of how often that word appears in the file:
while ( fscanf( fpointer, "%s", ch ) != EOF ) // whitespace is your friend, use it
{
if ( ch_is_not_already_in_str )
{
strcpy( str[count++], ch );
}
else
{
update_count_for_that_string;
}
}
Then at the end, you just loop through ch and print each string that has a count greater than 1.
for ( i = 0; i < count; i++ )
{
if ( str[i]_occurs_more_than_once )
printf( "%s ", str[i] );
}
The bits you need to figure out are ch_is_not_already_in_str, update_count_for_that_string, and str[i]_occurs_more_than_once. How would you go about searching your str array for an occurence of the string in ch? How would you maintain a counter for each string?
Related
I made a program that reads the output from a text file line by line and puts it into an array. So I got an array of strings.
The problem arises when I go through that array of strings and check if those strings meet certain conditions. When I form an array of strings that meet a certain condition, I get empty lines as array elements.
For Example:
Expressions in a text file:
X&Y
X|Y
!X
(X|Y)|Z
(X&Y)|Z
(X&Y)&Z
(X&Y)|Z&(A|B
((X|Y)|Z)&((A|B)|(C&D))
(X&Y)|(Z&(A|B))
(A|B)&(!C)
A|(B&(C&(D|E)))
((X|Y)|(Z&(A|B)))|((C&D)&(D|E))
(A|B)|(C&D)&(D|E)
!A&(B|C)
(A|B)|(C|D)&(D
!A|(B&C)
When I print a new array of strings whose elements meet a certain condition, I get empty lines as elements.
X&Y
X|Y
!X
(X|Y)|Z
(X&Y)|Z
(X&Y)&Z
//Here
((X|Y)|Z)&((A|B)|(C&D))
(X&Y)|(Z&(A|B))
(A|B)&(!C)
A|(B&(C&(D|E)))
((X|Y)|(Z&(A|B)))|((C&D)&(D|E))
(A|B)|(C&D)&(D|E)
!A&(B|C)
//Here
Some elements that should be printed are not printed because of those empty lines? Can someone help me remove these empty lines?
Here's code:
int main()
{
FILE *dat;
int number_of_elements;
char str[MAX][MAXLEN];
int NumberOfRightBracket=0;
int NumberOFLeftBracket=0;
int NumberOfOperators=0;
int Number=0;
int i=0;
char g[200][MAXLEN];
dat=fopen("dat.txt","r");
if(dat==NULL)
{
printf("Error");
}
while(!feof(dat) && !ferror(dat))
{
if(fgets(str[i],100,dat)!=NULL)
str[i][strcspn(str[i],"\n")] = 0;
char p[100];
strcpy(p,str[i]);
for(int o=0;o<strlen(p);o++)
{
if(p[o]=='(')
NumberOfLeftBracket++;
else if(p[o]==')')
NumberOfRightBracket++;
else if(p[o]=='*' || p[o]=='|' || p[o]=='&' || p[o]=='!')
NumberOfOperators++;
}
if(NumberOfRightBracket!=0 && NumberOfLeftBracket!=0 && NumberOfRightBracket==NumberOfLeftBracket)
{
strcpy(g[i],p);
Number++;
}
else if(NumberOfRightBracket==0 && NumberOfLeftBracket==0 && NumberOfOperators==1)
{
strcpy(g[i],p);
Number++;
}
NumberOfRightBracket=0;
NumberOfLeftBracket=0;
NumberOfOperators=0;
i++;
}
for(int k=0;k<Number;k++)
{
printf("%s\n",g[k];
}
}
You use i to decide where in g to store each line from the input, and i is incremented in every iteration, but you use Number to count the number of retained strings, and you only increment Number when retaining a string.
The result is various g[i] where you decided not to retain a string never get updated with data from a line, but you do print them.
You do not need both i and Number. Use just one variable to keep track of both how many lines you have so far and where to put the next line in g.
(You also do not need g if the program is only supposed to do what it appears to be currently attempting.)
I'm trying to create a complete C program to read ten alphabets and display them on the screen. I shall also have to find the number of a certain element and print it on the screen.
#include <stdio.h>
#include <conio.h>
void listAlpha( char ch)
{
printf(" %c", ch);
}
int readAlpha(){
char arr[10];
int count = 1, iterator = 0;
for(int iterator=0; iterator<10; iterator++){
printf("\nAlphabet %d:", count);
scanf(" %c", &arr[iterator]);
count++;
}
printf("-----------------------------------------");
printf("List of alphabets: ");
for (int x=0; x<10; x++)
{
/* I’m passing each element one by one using subscript*/
listAlpha(arr[x]);
}
printf("%c",arr);
return 0;
}
int findTotal(){
}
int main(){
readAlpha();
}
The code should be added in the findTotal() element. The output is expected as below.
Output:
List of alphabets : C C C A B C B A C C //I've worked out this part.
Total alphabet A: 2
Total alphabet B: 2
Total alphabet C: 6
Alphabet with highest hit is C
I use an array to count the number of the existence of each character,
I did this code but the display of number of each character is repeated in the loop
int main()
{
char arr[100];
printf("Give a text :");
gets(arr);
int k=strlen(arr);
for(int iterator=0; iterator<k; iterator++)
{
printf("[%c]",arr[iterator]);
}
int T[k];
for(int i=0;i<k;i++)
{
T[i]=arr[i];
}
int cpt1=0;
char d;
for(int i=0;i<k;i++)
{int cpt=0;
for(int j=0;j<k;j++)
{
if(T[i]==T[j])
{
cpt++;
}
}
if(cpt>cpt1)
{
cpt1=cpt;
d=T[i];
}
printf("\nTotal alphabet %c : %d \n",T[i],cpt);
}
printf("\nAlphabet with highest hit is : %c\n",d,cpt1);
}
There is no way to get the number of elements You write in an array.
Array in C is just a space in the memory.
C does not know what elements are actual data.
But there are common ways to solve this problem in C:
as mentioned above, create an array with one extra element and, fill the element after the last actual element with zero ('\0'). Zero means the end of the actual data. It is right if you do not wish to use '\0' among characters to be processed. It is similar to null-terminated strings in C.
add the variable to store the number of elements in an array. It is similar to Pascal-strings.
#include <stdio.h>
#include <string.h>
#define ARRAY_SIZE 10
char array[ARRAY_SIZE + 1];
int array_len(char * inp_arr) {
int ret_val = 0;
while (inp_arr[ret_val] != '\0')
++ret_val;
return ret_val;
}
float array_with_level[ARRAY_SIZE];
int array_with_level_level;
int main() {
array[0] = '\0';
memcpy(array, "hello!\0", 7); // 7'th element is 0
printf("array with 0 at the end\n");
printf("%s, length is %d\n", array, array_len(array));
array_with_level_level = 0;
const int fill_level = 5;
int iter;
for (iter = 0; iter < fill_level; ++iter) {
array_with_level[iter] = iter*iter/2.0;
}
array_with_level_level = iter;
printf("array with length in the dedicated variable\n");
for (int i1 = 0; i1 < array_with_level_level; ++i1)
printf("%02d:%02.2f ", i1, array_with_level[i1]);
printf(", length is %d", array_with_level_level);
return 0;
}
<conio.h> is a non-standard header. I assume you're using Turbo C/C++ because it's part of your course. Turbo C/C++ is a terrible implementation (in 2020) and the only known reason to use it is because your lecturer made you!
However everything you actually use here is standard. I believe you can remove it.
printf("%c",arr); doesn't make sense. arr will be passed as a pointer (to the first character in the array) but %c expects a character value. I'm not sure what you want that line to do but it doesn't look useful - you've listed the array in the for-loop.
I suggest you remove it. If you do don't worry about a \0. You only need that if you want to treat arr as a string but in the code you're handling it quite validly as an array of 10 characters without calling any functions that expect a string. That's when it needs to contain a 0 terminator.
Also add return 0; to the end of main(). It means 'execution successful' and is required to be conformant.
With those 3 changes an input of ABCDEFGHIJ produces:
Alphabet 1:
Alphabet 2:
Alphabet 3:
Alphabet 4:
Alphabet 5:
Alphabet 6:
Alphabet 7:
Alphabet 8:
Alphabet 9:
Alphabet 10:-----------------------------------------List of alphabets: A B C D E F G H I J
It's not pretty but that's what you asked for and it at least shows you've successfully read in the letters. You may want to tidy it up...
Remove printf("\nAlphabet %d:", count); and insert printf("\nAlphabet %d: %c", count,arr[iterator]); after scanf(" %c", &arr[iterator]);.
Put a newline before and after the line of minus signs (printf("\n-----------------------------------------\n"); and it looks better to me.
But that's just cosmetics. It's up to you.
There's a number of ways to find the most frequent character. But at this level I recommend a simple nested loop.
Here's a function that finds the most common character (rather than the count of the most common character) and if there's a tie (two characters with the same count) it returns the one that appears first.
char findCommonest(const char* arr){
char commonest='#'; //Arbitrary Bad value!
int high_count=0;
for(int ch=0;ch<10;++ch){
const char counting=arr[ch];
int count=0;
for(int c=0;c<10;++c){
if(arr[c]==counting){
++count;
}
}
if(count>high_count){
high_count=count;
commonest=counting;
}
}
return commonest;
}
It's not very efficient and you might like to put some printfs in to see why!
But I think it's at your level of expertise to understand. Eventually.
Here's a version that unit-tests that function. Never write code without a unit test battery of some kind. It might look like chore but it'll help debug your code.
https://ideone.com/DVy7Cn
Footnote: I've made minimal changes to your code. There's comments with some good advice that you shouldn't hardcode the array size as 10 and certainly not litter the code with that value (e.g. #define ALPHABET_LIST_SIZE (10) at the top).
I have used const but that may be something you haven't yet met. If you don't understand it and don't want to learn it, remove it.
The terms of your course will forbid plagiarism. You may not cut and paste my code into yours. You are obliged to understand the ideas and implement it yourself. My code is very inefficient. You might want to do something about that!
The only run-time problem I see in your code is this statement:
printf("%c",arr);
Is wrong. At this point in your program, arr is an array of char, not a single char as expected by the format specifier %c. For this to work, the printf() needs to be expanded to:
printf("%c%c%c%c%c%c%c%c%c%c\n",
arr[0],arr[1],arr[2],arr[3],arr[4],
arr[5],arr[6],arr[7],arr[8],arr[9]);
Or: treat arr as a string rather than just a char array. Declare arr as `char arr[11] = {0};//extra space for null termination
printf("%s\n", arr);//to print the string
Regarding this part of your stated objective:
"I shall also have to find the number of a certain element and print it on the screen. I'm new to this. Please help me out."
The steps below are offered to modify the following work
int findTotal(){
}
Change prototype to:
int FindTotal(char *arr);
count each occurrence of unique element in array (How to reference)
Adapt above reference to use printf and formatting to match your stated output. (How to reference)
I've been asked to find the number of characters that are compared during naive string matching. This was the function we were asked to implement:
// Count the number of characters compared while finding all occurences of the pattern in the given text
// Characters must be matched from left to right
int charactersCompared(char *pattern, char *text);
So if the text is:"ABCEDF" and the pattern is: "EF" the number of characters I would compare using the brute force method would be 6 (comparing the first letter of text with the first letter of the pattern. If it does not match, compare the second letter of the text with the first letter of the pattern again.
If it matches, continue with the comparing the next letters of both text and pattern and so on)
After figuring out a logic with many example cases, I implemented the above function this way:
int charactersCompared(char *pattern, char *text)
{
int i,j,comp=0;
int flag;
for(i=0;text[i]!='\0';i++) //iterating through all the letters of text
{
for(j=0;pattern[j]!='\0';j++)
{
comp++; //to count one comparision.
if(text[i+j]==pattern[j]) //to check if similar to pattern
{
flag=1;
continue;
}
else
{
if(flag==1)
{
flag=0;
comp--;
}
break;
}
}
}
//printf("VALUE OF C=%d\n",comp);
return comp;
}
This works fine for the pair(ABCDEF,EF) (where the count is 6) but not for other test cases which include multiple occurrences of the pattern in text such as:
Text: ABCDEFGHEIEF
Pattern: EF
I'm supposed to get 14 comparisions whereas my output is 12. I don't understand where I am missing out.
If anyone can point out what is the faulty logic, it'd be of great help. Or if there is an easier way to do this, suggestions appreciated. The only constraint is that the method has to be a brute force method (i.e I can't really change the part where i compare each character of each string).
Thank you for your time!
Please note that in worse case is n(m-n+1) , where n is length of pattern and m is length of text. Now, Since you only want to compute comparisons, there's no need for variable flag. Prefer KISS principle.
for(i=0;text[i]!='\0';i++) //iterating through all the letters of text
{
for(j=0;pattern[j]!='\0';j++)
{
comp++; //to count one comparison.
if(text[i+j]==pattern[j]) //to check if similar to pattern
continue;
break;
}
}
printf("VALUE OF C=%d\n",comp);
So i figured out why my program incremented comp extra number of times in the answer posted by #E.N.D . It was because the outer for loop continued until each letter in the text was not compared. But when we do it manually, it's only until the the number of letters remaining in text while comparision are equal to or more than the number of letters in pattern. So i changed a condition
int charactersCompared(char *pattern, char *text)
{
int i,j,comp=0; //int flag;
int lenp=length(pattern),lent=length(text);
for(i=0;i<=lent-lenp;i++)
{
for(j=0;pattern[j]!='\0';j++)
{
comp++;
if(text[i+j]==pattern[j])
{
continue;
}
break;
}
}
//printf("VALUE OF C=%d\n",c);
return comp;
}
This makes sense and works! Thanks for those who tried to answer!
I'm trying to make a simple encryption program in C. My aim is to translate "jim" (it can be any word) to 10,9,13. Then plus 1,2,3(because word has 3 letter) and get 11,12,16 then again translate to text, then write on screen klp.I have 2 algorithm one for encryption and second one for return first one.It s working but for these words there s problem
"compiler you executable through" when i start first algorithm and then second algortihm(inverse) i took ."compileo vou euecrqable throrgh "i checked algorithm several times i dont know where i overlooked
PS:if u want to run make txt file which named unencrypted.txt and write word inside then first algorithm then second one
int main() {
int g,z,o,c,l,i,j,k,*D;
char alfabe[26]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
FILE *fp1;
FILE *mat;
char word[20];
fp1 = fopen("unencrypted.txt","r+");
do {
g = fscanf(fp1,"%s",word);
if (g != EOF) {
mat=fopen("encrypted.txt","a+");
c=strlen(word);
D=(int*)calloc(c,sizeof(int));
for(i=0;i<c;i++) {
for(j=0;j<26;j++) {
if(word[i]==alfabe[j]) {
D[i]=(((j+1)+(i+1))%26);
break;
}
}
}
}
for(z=0;z<c;z++){
o=D[z];
word[z]=alfabe[o-1];
}
for(k=0;k<c;k++) {
fprintf(mat,"%c",word[k]);
}
fprintf(mat," ");
fclose(mat);
} while (g != EOF);
fclose(fp1);
}
int main() {
int g,z,o,c,l,i,j,k,*D;
char alfabe[26]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
FILE *fp1;
FILE *mat;
char word[20];
fp1 = fopen("encrypted.txt","a+");
do {
g = fscanf(fp1,"%s",word);
if (g != EOF) {
mat=fopen("unencrypted1.txt","a+") ;
c=strlen(word);
D=(int*)calloc(c,sizeof(int));
for(i=0;i<c;i++) {
for(j=0;j<26;j++) {
if(word[i]==alfabe[j]) {
if(0>((j+1)-(i+1))){
D[i]=((j+1)-(i+1)+26);
} else D[i]=((j+1)-(i+1));
break;
}
}
}
}
for(z=0;z<c;z++){
o=D[z];
word[z]=alfabe[o-1];
}
for(k=0;k<c;k++) {
fprintf(mat,"%c",word[k]);
}
fprintf(mat," ");
fclose(mat);
} while (g != EOF);
fclose(fp1);
}
First, in your encryption routine, you can have undefined behaviour:
word[z]=alfabe[o-1];
accesses memory it shouldn't if o == 0, which will happen if the sum of 1-based index of the character in the word and 1-based index in the alphabet is a multiple of 26.
To avoid that, you can set word[z] = alfabe[(o+25)%26], or, simpler, leave off one of the +1s in the previous loop and use alfabe[o].
The access of alfabe[-1], if it happens, is the sort of undefined behaviour that is unlikely to cause a segmentation fault or similar drastic things, it will probably only cause an unexpected byte to be written in the encrypted word.
In the decryption, you have similar problems,
if(0>((j+1)-(i+1))){
D[i]=((j+1)-(i+1)+26);
} else D[i]=((j+1)-(i+1));
If the word is long enough, even j - i + 26 may be negative (that is, however, extremely unlikely for natural English text - also in a lot of other languages).
And again, it can happen that D[i] is set to 0, in which case
for(z=0;z<c;z++){
o=D[z];
word[z]=alfabe[o-1];
}
will again access alfabe[-1] and cause undefined behaviour.
Note also that if your input contains anything except lower case letters and whitespace (which is discarded by the fscanf), the corresponding entry of the D array contains whatever bytes occurred to be at that memory location, again causing undefined behaviour.
If your input contains only lower case letters (and whitespace), you can find the index in the alphabet much easier than with the loop by setting
j = word[i] - 'a';
To avoid the alfabe[-1] issues, I recommend using 0-based indices.
I'm actually writing about the same program as before, but I feel like I've made significant progress since the last time. I have a new question however; I have a function designed to store the frequencies of letters contained within the message inside an array so I can do some comparison checks later. When I ran a test segment through the function by outputting all of my array entries to see what their values are, it seems to be storing some absurd numbers. Here's the function of issue:
void calcFreq ( float found[] )
{
char infname[15], alpha[27];
char ch;
float count = 0;
FILE *fin;
int i = 0;
while (i < 26) {
alpha[i] = 'A' + i++;
}
printf("Please input the name of the file you wish to scan:\n");
scanf("%s", infname);
fin = fopen ( infname, "r");
while ( !feof(fin) ) {
fscanf(fin, "%c", &ch);
if ( isalpha(ch) ) {
count += 1;
i = 0;
if ( islower(ch) ) { ch = toupper(ch); }
while ( i < 26 ) {
if ( ch == alpha[i] ) {
found[i]++;
i = 30;
}
i++;
}
}
}
fclose(fin);
i = 0;
while ( i < 26 ) {
found[i] = found[i] / count;
printf("%f\n", found[i]);
i++;
}
}
At like... found[5], I get this hugely absurd number stored in there. Is there anything you can see that I'm just overlooking? Also, some array values are 0 and I'm pretty certain that every character of the alphabet is being used at least once in the text files I'm using.
I feel like a moron - this program should be easy, but I keep overlooking simple mistakes that cost me a lot of time >.> Thank you so much for your help.
EDIT So... I set the entries to 0 of the frequency array and it seems to turn out okay - in a Linux environment. When I try to use an IDE from a Windows environment, the program does nothing and Windows crashes. What the heck?
Here are a few pointers besides the most important one of initializing found[], which was mentioned in other comments.
the alpha[] array complicates things, and you don't need it. See below for a modified file-read-loop that doesn't need the alpha[] array to count the letters in the file.
And strictly speaking, the expression you're using to initialize the alpha[] array:
alpha[i] = 'A' + i++;
has undefined behavior because you modify i as well as use it as an index in two different parts of the expression. The good news is that since you don't need alpha[] you can get rid of its initialization entirely.
The way you're checking for EOF is incorrect - it'll result in you acting on the last character in the file twice (since the fscanf() call that results in an EOF will not change the value of ch). feof() won't return true until after the read that occurs at the end of the file. Change your ch variable to an int type, and modify the loop that reads the file to something like:
// assumes that `ch` is declared as `int`
while ( (ch = fgetc(fin)) != EOF ) {
if ( isalpha(ch) ) {
count += 1;
ch = toupper(ch);
// the following line is technically non-portable,
// but works for ASCII targets.
// I assume this will work for you because the way you
// initialized the `alpha[]` array assumed that `A`..`Z`
// were consecutive.
int index = ch - 'A';
found[index] += 1;
}
}
alpha[i] = 'A' + i++;
This is undefined behavior in C. Anything can happen when you do this, including crashes. Read this link.
Generally I would advise you to replace your while loops with for loops, when the maximum number of iterations is already known. This makes the code easier to read and possibly faster as well.
Is there a reason you are using float for counter variables? That doesn't make sense.
'i = 30;' What is this supposed to mean? If your intention was to end the loop, use a break statement instead of some mysterious magic number. If your intention was something else, then your code isn't doing what you think it does.
You should include some error handling if the file was not found. fin = fopen(..) and then if(fin == NULL) handle errors. I would say this is the most likely cause of the crash.
Check the definition of found[] in the caller function. You're probably running out of bounds.