gpt4 book ai didi

c - 为什么这两种计算字数的方法有很大不同?

转载 作者:行者123 更新时间:2023-11-30 15:24:50 24 4
gpt4 key购买 nike

我编写了一个程序,允许用户查找任何文本文件中单词或单词集合的实例数。用户可以在命令行中输入如下内容:

$ ./wordCount Mars TripToMars.txt

搜索《火星之旅》一书中“火星”一词的出现次数,或

$ ./wordCount -f collectionOfSearchWords.txt TripToMars.txt

搜索 collectionOfSearchWords.txt 中各行上多个单词的实例数。

为了确保程序正确,我使用了 grep 命令:

$ grep -o 'Mars' TripToMars.txt | wc -w

$ grep -o -w 'Mars' TripToMars.txt | wc -w

第一个命令查找任意位置的单词实例数,其中包括“Marsa”、“Marseen”、“Marses”等术语,而第二个命令仅查找“Mars”作为独立词的实例单词,其中包括尾随标点符号,例如“Mars.”、“Mars!”、“Mars?”等。

两个 grep 命令都返回 49 作为书中“Mars”的实例数。

当我在下面的 while 循环中使用代码时(为简单起见,我只包含相关代码),程序返回 49。太棒了!

FILE *textToSearch;
char *readMode = "r";

int count;
char nextWord[100];
char d;

textToSearch = fopen(argVector[argCount-1], readMode);
if (textToSearch == NULL) {
fprintf(stderr, "Cannot open %s to be searched\n", argVector[argCount-1]);
return 1;
} else {
while (fscanf(textToSearch, "%*[^a-zA-Z]"), fscanf(textToSearch, "%80[a-zA-Z]", nextWord) > 0) {

// increment the counter if the word is a match
if (strcmp(nextWord, argVector[word]) == 0) {
count++;
}
}
}

但是当我用这个 while 循环替换前一个循环时,程序返回 17。

while(1) {
d = fscanf(textToSearch, "%s", nextWord);
if (d == EOF) break;

// increment the counter if the word is a match
if (strcmp(nextWord, argVector[word]) == 0) {
count++;
}
}

那么,两者之间最大的区别是什么

while (fscanf(textToSearch, "%*[^a-zA-Z]"), fscanf(textToSearch, "%80[a-zA-Z]", nextWord) > 0) {}

while(1) {
d = fscanf(textToSearch, "%s", nextWord);
if (d == EOF) break;
}

编辑:

我添加了这段代码:

if (strcmp(nextWordDict, nextWord) == 0 ||
strcmp(nextWordDict, strcat(nextWord, ".")) == 0 ||
strcmp(nextWordDict, strcat(nextWord, "?")) == 0 ||
strcmp(nextWordDict, strcat(nextWord, "!")) == 0 ||
strcmp(nextWordDict, strcat(nextWord, ",")) == 0) {
count++;
}

为 Mars 生成 17 的代码尝试解释带有尾随标点符号的情况,但没有任何变化。还是17岁。

编辑2:

正如 John Bollinger 在下面正确指出的那样,此代码不执行任何操作,因为缓冲到 nextWord 中的字符串已经具有尾随标点符号,并且代码只会添加更多标点符号。这是我的错误想法。

最佳答案

当您说该命令时,您是错误的...

$ grep -o -w 'Mars' TripToMars.txt | wc -w

...“仅查找‘Mars’作为独立单词的实例”,或者至少该陈述在上下文中具有误导性。该命令查找不属于较大单词的“Mars”实例,其中“单词”被定义为字母、数字和/或下划线的连续字符串。特别是,它将匹配“Mars”,后面跟着一个标点符号,这与您似乎声称的内容相冲突。

但是两种扫描方法有什么区别?嗯,这个...

while (fscanf(textToSearch, "%*[^a-zA-Z]"),
fscanf(textToSearch, "%80[a-zA-Z]", nextWord) > 0) { /* ... */ }

... 扫描零个或多个非拉丁字母的字符,忽略是否匹配以及是否发生输入错误,然后扫描最多 80 个拉丁字母的连续序列,将该序列记录在 nextWord 中 缓冲区。

另一方面,这...

while(1) {
d = fscanf(textToSearch, "%s", nextWord);
if (d == EOF) break;
}

...忽略前导空格,然后将下一个连续的非空格字符串扫描到 nextWord 中。

两者在处理既不是拉丁字母也不是空格的字符方面存在显着差异:前者忽略它们,而后者将它们包含在 nextWord 中。然后,当您将 nextWord 与字符串 "Mars" 进行比较时,后者会丢失

Going to Mars.

The name "Mars"

Is there water on Mars?

因为相邻的标点符号也包含在比较中。您的文本很可能有许多与这些类似的结构,并且您的 grep 命令不会显示其他情况。

关于c - 为什么这两种计算字数的方法有很大不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28200183/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com