[编辑]
1. 用 calloc 替换 malloc(将内存初始化为 0)
2. 替换 qsort 中的第二个参数
3. 程序现在可以处理更广泛的文件(更多单词,更多分隔符)
这并不漂亮,可能需要一些小的调试,但它会让你开始计数,不同的和最常用的单词的数量:
#include <ansi_c.h>
#include <stdio.h>
#define FILENAME "c:\\dev\\play\\test3.txt" //put your own path here
#define DELIM "- .,:;//_*&\n"
int longestWord(char *file, int *cnt);
void allocMemory(int numStrings, int max);
void freeMemory(int numStrings);
static int sortstring( const void *str1, const void *str2 );
char **strings;
int main()
{
int wc, longest, cnt, distinct, i, mostFreq, mostFreqKeep=0;
char line[260];
char *buf=0;
FILE *fp;
longest = longestWord(FILENAME, &wc);
char wordKeep[longest];
allocMemory(wc, longest);
//read file into string arrays
fp = fopen(FILENAME, "r");
cnt=0;
while(fgets(line, 260, fp))
{
buf = strtok(line, DELIM);
while(buf)
{
if((strlen(buf) > 0) && (buf[0] != '\t') && (buf[0] != '\n') && (buf[0] != '\0')&& (buf[0] > 0))
{
strcpy(strings[cnt], buf);
cnt++; //use as accurate count of words.
}
buf = strtok(NULL, DELIM);
}
}
fclose(fp);
//now get most frequent word
//sort
qsort(strings, cnt, sizeof(char*), sortstring);
distinct = 1;
mostFreq = 1; //every word will occur once
wordKeep[0]=0;
for(i=0;i<cnt-1;i++)
{
//depends on a successful sort (alphabetization)
if(strlen(strings[i]) >0)
{
if(strcmp(strings[i], strings[i+1]) == 0)
{
mostFreq++;
if(mostFreq > mostFreqKeep)
{
strcpy(wordKeep, strings[i]);
mostFreqKeep = mostFreq;
}
}
else
{
mostFreq = 1;
distinct++;
}
}
}
printf("number of words: %d\nNumber of distinct words:%d\nmost frequent word: %s - %d\n", cnt, distinct, wordKeep, mostFreqKeep);
freeMemory(cnt);
getchar();
return 0;
}
int longestWord(char *file, int *nWords)
{
FILE *fp;
int cnt=0, longest=0, numWords=0;
char c;
fp = fopen(file, "r");
while ( (c = fgetc ( fp) ) != EOF )
{
if ( isalpha ( c ) ) cnt++;
else if ( ( ispunct ( c ) ) || ( isspace ( c ) ) )
{
(cnt > longest) ? (longest = cnt, cnt=0) : (cnt=0);
numWords++;
}
}
*nWords = numWords;
fclose(fp);
return longest+1;
}
void allocMemory(int numStrings, int max)
{
int i;
strings = calloc(sizeof(char*)*(numStrings+1), sizeof(char*));
for(i=0;i<numStrings; i++)
{
strings[i] = calloc(sizeof(char)*max + 1, sizeof(char));
}
}
void freeMemory(int numStrings)
{
int i;
for(i=0;i<numStrings; i++)
if(strings[i]) free(strings[i]);
free(strings);
}
static int sortstring( const void *str1, const void *str2 )
{
const char *rec1 = *(const char**)str1;
const char *rec2 = *(const char**)str2;
int val = strcmp(rec1, rec2);
return val;
}