我想制作一个程序来计算与我已经创建的文件相同的单词数。我怀疑我将如何实施它。现在我有这个代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char word[100];
FILE *file;
file=fopen("hello.txt", "r");
if(file == NULL)
{
printf("Error\n");
exit(0);
}
printf("Write a word.\n");
fgets(word, 100, stdin);
return 0;
}
使用此代码,我可以获得用户希望的单词,但现在我不知道下一步该做什么来计算该单词出现在文件上的次数。有人可以帮忙吗?
[编辑]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char word[100],oriword[100], c;
int cont=0, condition;
FILE *file;
file=fopen("hello.txt", "r");
if(file == NULL)
{
printf("Error\n");
exit(0);
}
printf("Write a word.\n");
fgets(word, 100, stdin);
do
{
c=fscanf(file, "%s", oriword);
condition=strcmp(word, oriword);
printf("%d ", condition);
if(condition==0)
cont=cont+1;
}while(c != EOF);
printf("That word appears %d times\n", cont);
fclose(file);
return 0;
}
我现在能够阅读每个单词,谢谢你们。我试着计算同一个单词出现的次数但是用这个代码我还是没有用。看起来像strcmp值永远不会返回0(我输入了一个文件内的单词)。我做错了什么?
答案 0 :(得分:0)
你很亲密,但有一个问题。 fgets的输出不是你想象的那样。而不是尝试使用fgets,只使用scanf就更有意义了:
scanf("%s", word);
我还清理了一下文件并创建了一个样本hello.txt,你可以看到下面的结果。
hello.txt的:
hello world hi world
wordcount.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char word[100],oriword[100];
int count=0;
FILE *file;
file=fopen("hello.txt", "r");
if(file == NULL)
{
printf("Error\n");
exit(0);
}
printf("Write a word.\n");
//fgets(word, 100, stdin);
scanf("%s", word);
printf("Got %s\n",word);
while(fscanf(file, "%s", oriword) != EOF)
{
if(strcmp(word, oriword))
{
count=count+1;
printf("Match of %s so far %d have been found\n",word, count);
}
printf("Found %s\n",oriword);
}
printf("That word appears %d times\n", count);
fclose(file);
return 0;
}
结果:
Write a word.
world
Got world
Found hello
Match of world so far 1 have been found
Found world
Found hi
Match of world so far 2 have been found
Found world
That word appears 2 times
答案 1 :(得分:0)
你很接近,但你遇到的问题是你必须将阅读时的每个单词与你从文件中读到的所有单词进行比较。为此,您必须跟踪已阅读的所有唯一字词,并且只将您以前从未见过的字词添加到您的字词集合中。如果你之前看过一个单词,你只想更新你看过这个单词的次数。
虽然理想情况下您不知道文件可以包含多少单词,或文件有多大,但您可能需要某种方式来分配内存以根据需要存储单词。但是,出于本示例的目的,我们将设置要处理的最大字数,以防止分配/管理内存所需的代码混淆了如何保存单词的逻辑并计算它们被看到的次数。 / p>
为此,我们将通过定义MAXW
的字词限制100
来设置要处理的最大字词数。对于MAXC
的任何一个单词32
中的最大字符,我们也会这样做(删节词典中最长的单词是28个字符,所以32个单词会这样做。)
要存储我们从文件中读取的所有单词,我们将创建一个数组'read'来表示我们已阅读的唯一单词并将其声明为:
char read[MAXW][MAXC] = {{ 0 }};
我们将声明一个名为'word'的临时缓冲区来保存当前单词并将其声明为:
char word[MAXC] = {0};
虽然fgets
通常是从文件中读取行的正确选择,但这是少数情况之一,可以使用fscanf
而不必折磨格式规范以适应数据。 fscanf
的格式字符串可以很好地工作:
fscanf (fp, " %32[^ ,.\n]%*c", word);
最多会读取32
个字符,不包括空格逗号句号或换行符([^ ,.\n]
),然后读取并丢弃空格逗号句号或换行符(%*c
)。
我们将跟踪我们看到每个单词的次数,其中seen
数组声明如下:
size_t seen[MAXW] = {0};
剩下的就是将我们读取的唯一字添加到read
数组的逻辑,并更新我们在seen
数组中看到它们的次数。我没有对每一步感到烦恼,而是评论了一个简短的例子,它将帮助你完成逻辑:
#include <stdio.h>
#include <string.h>
#define MAXW 100
#define MAXC 32
int main (int argc, char **argv) {
/* initialize variables & open file or stdin for reading */
char read[MAXW][MAXC] = {{ 0 }};
char word[MAXC] = {0};
size_t seen[MAXW] = {0};
size_t i, idx = 0;
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) {
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
/* read 1st word into 'read' array, update index 'idx' */
if (fscanf (fp, " %32[^ ,.\n]%*c", word) == 1) {
strcpy (read[idx], word);
seen[idx]++;
idx++;
}
else {
fprintf (stderr, "error: file read error.\n");
return 1;
}
/* read each word in file */
while (fscanf (fp, " %32[^ ,.\n]%*c", word) == 1) {
/* check against all prior words */
for (i = 0; i < idx; i++) {
/* if word already in 'read', update 'seen' count */
if (strcmp (read[i], word) == 0) {
seen[i]++;
goto present; /* skip adding word to 'read' */
}
} /* add unseen words to 'read', update 'idx' */
strcpy (read[idx], word);
seen[idx]++;
idx++;
present:
if (idx == MAXW) { /* check 'idx' against MAXW */
fprintf (stderr, "warning: MAXW words exceeded.\n");
break;
}
}
if (fp != stdin) fclose (fp);
printf ("\nthe occurrence of words are:\n\n");
for (i = 0; i < idx; i++)
printf (" %-28s : %zu\n", read[i], seen[i]);
return 0;
}
我整理了一个不会超出我们限制的简短无意义的测试文件:
<强>输入强>
$ cat dat/words.txt
the quick brown fox jumps over the lazy dog. the fox jumps over the dog to avoid the squirrel.
the squirrel was in the path of captain jack sparrow a pirate so brave on the seven seas.
通过代码运行测试文件将生成唯一的单词列表以及每次查看时的计数:
<强>输出强>
$ ./bin/file_words_occur <dat/words.txt
the occurrence of words are:
the : 8
quick : 1
brown : 1
fox : 2
jumps : 2
over : 2
lazy : 1
dog : 2
to : 1
avoid : 1
squirrel : 2
was : 1
in : 1
path : 1
of : 1
captain : 1
jack : 1
sparrow : 1
a : 1
pirate : 1
so : 1
brave : 1
on : 1
seven : 1
seas : 1
如果您有任何疑问,请与我们联系。唯一可能导致你挠头的方法是用来打开作为程序的第一个参数提供的文件或从stdin
读取的简写:
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
这只是一个三元运算符,表示如果你有一个参数argc > 1 ?
,那么如果不是fopen (argv[1], "r")
则使用它作为文件名:
,然后从stdin
读取。这只是一种方便的方式来说明5行代码。