我正在尝试创建一个 C 程序来处理输入文件并查找字数统计/解剖信息(字数、最长单词的长度、最常见的单词大小及其频率等)。
我大致了解如何做到这一点,但是当使用
fgets
作为循环的条件来逐行处理输入文件时,我的程序甚至从未到达循环体,从而产生意外的结果。
到目前为止我有以下代码:
// This program reads all lines of an input file and generates
// a report including:
// Number of words in the file
// Which word size occurs the most and how many times
// Largest word length and its frequency
// All words of the longest word length of the file
// (duplicates not reported)
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define MAXW 300 // max total words
#define MAXC 17 // max chars in a word
#define MAXLINEW 82 // max chars to a line
#define MAXLINE 30 // max number of lines
const char *clean(char *src);
int getWords(char (*words)[MAXC], FILE *f);
int main(char **argv) {
char words[MAXC][MAXW] = {{0}};
int num_words = 0;
size_t i;
FILE *f = fopen("input.txt", "r");
if (!f) {
fprintf (stderr, "ERROR: Unable to open file '%s'.\n", argv[1]);
return 1;
}
num_words = getWords(words, f);
printf("Num words = %d\n", num_words);
fclose(f);
}
const char *clean(char *src) {
char *dst;
for (; *src; ++src) {
if (!ispunct((unsigned char)*src))
*dst++ = tolower((unsigned char)*src);
*dst = 0;
}
return dst;
}
int getWords(char (*words)[MAXC], FILE *f) {
int word_cnt = 0;
int r;
char p = NULL;
char lines[MAXLINE][MAXLINEW];
char buf[MAXLINEW];
static const char delims[] = " \n";
r = 0;
while (fgets(buf, MAXLINEW, f)) {
// find the next word
if (p == NULL) {
p = strtok(buf, delims);
while (p) {
const char c = clean(p);
strcpy(words[word_cnt], c);
word_cnt++;
p = strtok(NULL, delims);
}
}
}
}
我尝试使用
fgets
分割输入文件的每一行,然后使用 strtok
处理每一行以获取每个单词(由换行符空格分隔)。通过 strtok
对每个单词进行标记,我想将其传递给 clean
函数,该函数应该删除所有标点符号并将所有内容设为小写。清理单词后,我想将清理后的单词复制到所有单词的最终数组中,稍后我可以使用它来生成该程序所需的结果(计算单词长度/频率等)。
正如我之前所说,我的程序甚至从未到达
getWords
内部的 while 循环体,我不知道为什么。
我对 C 没有太多经验,但我确实了解 C++,所以如果我的代码缺少任何明显的东西,我很抱歉。
任何帮助将不胜感激,谢谢!
明显的错误是您将 clean
中单词的
cleaned版本存储到
*dst
,但该指针未初始化。
您应该就地修改源数组:
char *clean(char *src) {
char *result = src;
char *dst = src;
for (; *src; ++src) {
if (!ispunct((unsigned char)*src))
*dst++ = tolower((unsigned char)*src);
}
*dst = '\0';
return result;
}
又一个错误:
const char c = clean(p);
应该是
const char *c = clean(p);