提问人:Lumi 提问时间:11/1/2023 最后编辑:chqrlieLumi 更新时间:11/1/2023 访问量:49
使用 fgets/strtok 逐行处理输入文件
Processing an Input File Line-By-Line Using fgets/strtok
问:
我正在尝试创建一个 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
正如我之前所说,我的程序甚至从未到达 while 循环的主体,我不确定为什么。getWords
我对 C 没有太多经验,但我确实了解 C++,所以如果我的代码缺少任何明显的东西,我很抱歉。
任何帮助将不胜感激,谢谢!
答:
0赞
chqrlie
11/1/2023
#1
明显的错误是您将该单词的清理版本存储在 中,但此指针未初始化。clean
*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);
也缺少一个参数。用。int main(char **argv)
int main()
但请注意,无需存储单词即可计算请求的统计信息。只需编译数组中的字长并进行简单的数学运算即可产生预期的输出。
评论
strcpy(words[word_cnt], c);
c
char
char *
const char c = clean(p);
也。最大的问题是:/ - 你认为指向哪里?char *dst;
return dst;
dst
int getWords ()
缺少return
;int main (char **argv)
....缺少一个参数 - 就像如果这是 C++ 一样