Hey guys im 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 havent sorted yet. we are suppose to use qsort but i dont think my compare function is right. Any help would be greatly appreciated. Thank you.

Recommended Answers

All 9 Replies

Your compar function is wrong. qsort() sends two pointers to the compare function int compare(const void* s1, const void* s2) In your case it will send two strings, so your compare function needs to typecase the void* to char*

int compare(const void*s1, const void* s2)
{
   return strcmp((const char *)s1, (const char*)s2);
}

and this compare method will compare the word count?

It will compare the two strings:

strcmp(string1, string2);

If the return value is greater than 0, string1 has sorted higher than string2. If the answer is anything less than 0, then string2 has sorted higher.

string1 > string2, return > 0

string1 < string2, return < 0;

You can remember this, by seeing how the > symbols associate, in the above two lines.

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;
}

No idea what's wrong with it. I know what's wrong with this type of program development, though. What I see is:

1) If you want people to study your program, you need to put it between CODE tags, on the forum. Click on the CODE icon in the editor top bar, and paste your program between the tags it provides. Otherwise it looks like html text, and not a program.

2) Listen to your compiler - is it giving you any warning?

3) Learn to troubleshoot your program. Remove (/..../) calls to functions until you know which function has the error. You can do that, as well as anyone else.

4) Follow the steps in #3, to troubleshoot the lines of code in the troubled function, until you know which line of code is causing the crash.

5) Now study that line, and ask questions about THAT line of code, in your program.

6) This is made much easier if you build your program, and check it out, function by function - for accuracy and dependability. If it's all one big function, substitute "block of code" for the word function, here.

7) Some logic that looks fishy:

if (cur != '\n' && cur != '\0')
{
count2++;
}

What about periods and comma's and such? Check out the ispunct() function. You'll need to include ctype.h header file.

The first thing I would do is put in some print statements, and getchar()'s, right at the end of some blocks of code, or functions, (after the troubleshooting stuff above). See if you are first, getting the letters into words, then getting the words in your list array OK. And did you add the end of string char to each of those words so they could be handled nicely as strings?

A bunch of letters, does not a string make, in C. No ticky (no end of string marker: '\0'), no wash (string).

Ok the compiler I was using was acting retarded but on the new compiler it says my compare function is giving errors although i doubt that would cause my program to crash so soon.

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

ERRORS
In function âcompareâ:
20: warning: cast from pointer to integer of different size
20: warning: cast from pointer to integer of different size
24: warning: cast from pointer to integer of different size
24: warning: cast from pointer to integer of different size

if i comment out the first line shown then the program runs with no Segmentation fault but im not sure what the problem is.

while ((cur = fgetc(pFile))!= EOF)
    {
        if (cur != ' ')
        {
            list[m][k] = cur;
            fprintf(pFile2, "%c", list[m][k]);
            k++;

            if (cur != '\n' && cur != '\0')  
            {
                count2++;
            }

Why is your program reading the file one character at a time? Words are always separated with white space(s) (spaces and/or tabs). If you call fscanf() that function will read only words for you. You don't have to reinvent the wheel, but just use the functions that are already available to you.

Next you have to have some way to keep all those words in memory so that they can be counted. One way to do that is to have an array of structures, where the structure contains the word and an integer that is the count of the number of times that word appears in the file.

struct words
{
   struct words*next;
   char* word;
   int count;
};

That will let you maintain a linked list of the words. If you don't know about linked list yet then you can just make an array of those structures and increase the array size as necessary while reading the file. See malloc() and realloc() functions to do that.

When the program reads a word search the linked list or array for that word to see if its already in memory. I it is, then just increment the count variable. If it is not in the linked list or array you will have to add a new node.

Then you will have to sort the list in ascending order by the count. This is where that comparison function will have to be changed because qsort() will pass pointers to two of those structures. Notice that the if statements are not necessary. Simply return the subtraction of the two integers is sufficient.

int compare(const void*s1, const void* s2)
{
   struct words* w1 = (struct words*)s1;
   struct words* w2 = (struct words*)s2;
   return w1->count - w2->count;
};

You're on a roll with your troubleshooting - don't stop now!

Add a putc(cur) into the loop, and see what's going on. Ancient Dragon's suggestions are excellent, but you will HAVE to develop your troubleshooting skills, no matter how good a programmer you ultimately become.

Dig in there, be a stubborn badger, and find out what is going wrong. Trust me, you WON'T forget it, anytime soon, AND you will have learned a valuable less in how to troubleshoot code. Keep narrowing down the possible problems until you have it isolated and know it EXACTLY.

BE SURE that your compiler is a C compiler, and not a C++ compiler. That's an option in a lot of compiler's. They have both C and C++ bundled together in one product.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.