C Program Help: Count & Sort Word Occurrences in File

AI Thread Summary
The discussion revolves around troubleshooting a C program designed to count and sort word occurrences from a file. The user is struggling with segmentation faults and sorting functionality, particularly with the `qsort` implementation and the comparison function. Suggestions include using debugging techniques, such as adding print statements to identify where the segmentation fault occurs, and ensuring proper pointer usage in the code. Additionally, it is emphasized that the comparison function for `qsort` must correctly handle casting and comparisons of word counts. The conversation highlights the importance of debugging and proper memory management in C programming.
KV305
Messages
2
Reaction score
0
C program help!

Hey guys I am having trouble completing this C program. Its suppose to ask the user to enter a file to read from, read the file, count how many times each word appears and print the results in a different file(also user input) arranged from high occurrence.


Heres what i have so far

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct AWORD
{
char wordname[50];
int count;
}a_word;

a_word nword(char* words)
{
a_word new;
strcpy (new.wordname, words);
return new;
}

int compare (words.wordname, words[j].wordname)
{
if (words.count < words[j].count)
{
return -1;
}
else if (words.count > words[j].count)
{
return 1;
}
else
{
return 0;
}
}

int main(int argc, char *argv[])
{
int i = 0,j = 0,k = 0, m = 0, count = 0,count2 = 0, count3 = 0, wrdcnt = 1,$
char cur, cur2[50], file1[25], file2[25], list[1000][k], *buffer;
FILE *pFile, *pFile2;

printf("Please type the name of the input file:\n ");
scanf("%s",file1);
printf("%s",file1);
pFile = fopen(file1, "r");

printf("Please type the name of the output file:\n ");
scanf("%s",file2);
pFile2 = fopen(file2, "r");

while (cur != EOF)
{
cur = fgetc(pFile);
if (cur != ' ')
{
list[m][k] = cur;
fprintf(pFile2, "%c", list[m][k]);
k++;
if (cur != '\n' && cur != '\0')
{
count2++;
}
if (cur == '\n' || cur == '\0')
{
wrdcnt++;
}
}
else
{
if (cur == ' ')
{
wrdcnt++;
}
m++;
k = 0;
if (cur == '\0')
{
fprintf(pFile2,"%s", &cur);
}
else
{
fprintf(pFile2, "\n");
}
}
}
fclose(pFile);
fclose(pFile2);

pFile2 = fopen(file2, "r");

a_word words[wrdcnt];

for (i = 0; i < wrdcnt; i++)
{
fgets (cur2, 50, pFile2);
words = nword(cur2);
printf("words[%d] is %s", i, words.wordname);
}
printf("\n");
count3 = wrdcnt;
for (j = 0; j < count3; j++)
{
buffer = words[j].wordname;
for (i = 0; i < wrdcnt; i++)
{
if (strcmp(buffer, words.wordname) == 0)
{
count++;
}
}

words[j].count = count;
count = 0;
}
printf ("\nWord Counter Program Starting...");
printf("\nWord Counter Program Finished. Check %s file\n", file2);

for (j = 0; j < count3; j++)
{
for (i = 0; i < j; i++)
{
if (strcmp(words[j].wordname, words.wordname) == 0)
{
same = 0;
break;
}
else
{
same = 1;
}
}
if (same == 1)
{
printf ("%d\t%s", words[j].count, words[j].wordname);
fprintf(pFile2, "%d %s\n", words[j].count, words[j].wordname);

}

}
fclose(pFile2);
return 0;
}




I haven't sorted yet. we are suppose to use qsort but i don't think my compare function is right. Any help would be greatly appreciated. Thank you.
 
Physics news on Phys.org


You have to create a list of words and a number for each as you have done (AWORD).

You then need to do a bubble sort - going through your list of words swapping over any pair that are the wrong way round - you do that multiple times until there are no swaps - then you know it's done.
So you need to compare a pair of integers - the number of times each word occurs in each pair.

The declaration for the compare must use a void *. (it can't cope with overloading)
You will be passing it a pair of integers so you need to cast each to a const void* in the qsort call.
Then your declaration will look like:-

int compare (const void *count1, const void *count2)
{
//then you cast it back to the type you want - you can do that on-the-fly
// I think you can see where it goes from here
if ((int)count1==(int)count2) return 0; //etc.
}
 


Ok so far i altered the program and gives no errors but when i try to run it it says
"Segmentation fault"... any ideas?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct AWORD
{
char wordname[50];
int count;
}a_word;

a_word nword(char* words)
{
a_word new;
strcpy (new.wordname, words);
return new;
}

int compare (const void *count1, const void *count2)
{
if ((int)count1==(int)count2) return 0;
if ((int)count1<(int)count2) return -1;
if ((int)count1>(int)count2) return 1;
}

int main(int argc, char *argv[])
{
int i = 0,j = 0,k = 0, m = 0, count = 0,count2 = 0, count3 = 0, wrdcnt = 1,same;
char cur, cur2[50], file1[25], file2[25], list[1000][30], *buffer, sorted[1000];
FILE *pFile, *pFile2;

printf("Please type the name of the input file:\n ");
scanf("%s",file1);
printf("%s",file1);
pFile = fopen(file1, "r");

printf("Please type the name of the output file:\n ");
scanf("%s",file2);
pFile2 = fopen(file2, "r");

while (cur != EOF)
{
cur = fgetc(pFile);
if (cur != ' ')
{
list[m][k] = cur;
fprintf(pFile2, "%c", list[m][k]);
k++;
if (cur != '\n' && cur != '\0')
{
count2++;
}
if (cur == '\n' || cur == '\0')
{
wrdcnt++;
}
}
else
{
if (cur == ' ')
{
wrdcnt++;
}
m++;
k = 0;
if (cur == '\0')
{
fprintf(pFile2,"%s", &cur);
}
else
{
fprintf(pFile2, "\n");
}
}
}
fclose(pFile);
fclose(pFile2);

pFile2 = fopen(file2, "r");

a_word words[wrdcnt];

for (i = 0; i < wrdcnt; i++)
{
fgets (cur2, 50, pFile2);
words = nword(cur2);
printf("words[%d] is %s", i, words.wordname);
}
printf("\n");
count3 = wrdcnt;
for (j = 0; j < count3; j++)
{
buffer = words[j].wordname;
for (i = 0; i < wrdcnt; i++)
{
if (strcmp(buffer, words.wordname) == 0)
{
count++;
}
}

words[j].count = count;
count = 0;
}
printf ("\nWord Counter Program Starting...");
printf("\nWord Counter Program Finished. Check %s file\n", file2);

for (j = 0; j < count3; j++)
{
for (i = 0; i < j; i++)
{
if (strcmp(words[j].wordname, words.wordname) == 0)
{
same = 0;
break;
}
else
{
same = 1;
}
}
if (same == 1)
{
printf ("%d\t%s", words[j].count, words[j].wordname);
fprintf(pFile2, "%d %s\n", words[j].count, words[j].wordname);
}

}
fclose(pFile2);
pFile2 = fopen(file2, "r");
m=0;
while (pFile != NULL)
{
fscanf (pFile2 , "%s" , &sorted[m]);
m++;
}
qsort(sorted,m,sizeof(int),compare);
fclose(pFile2);
pFile2 = fopen(file2, "w");
fprintf(pFile2,"%s", sorted);
return 0;
}
 


Are you in the same class as the person who started this thread?

If you're getting a segmentation fault, you are probably attempting to access memory (via a pointer) that your program is not allowed to access. It's time to learn how to use a debugger.
 


KV305 said:
when i try to run it it says
"Segmentation fault"... any ideas?

Put extra printf() statements in the program so you can pin down exactly where the segmentation fault is occurring:

"I got to checkpoint #1.
I got to checkpoint #2.
I got to checkpoint #3.
ERROR: Segmentation fault."
 


It means you are attempting to read or write to a part of the memory outside your own program. Usually a pointer error (accessing memory location zero because a pointer is null for example).

Try temporarily commenting out sections of your program till you locate the line giving the error - then look carefully at any pointers involved.

Doesn't your debugger automatically stop at error points?
 
Back
Top