我编写了一个程序,该程序使用户可以在任何文本文件中查找单词或单词集合的实例数。用户可以在命令行中输入以下内容:
$ ./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”实例作为独立单词,因此包括尾随标点符号,例如“火星”,“火星!”,“火星?”等。
这两个grep命令都返回49作为书中“火星”的实例数。
当我在下面的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++;
}
产生17的代码,供火星尝试处理标点符号结尾的情况,并且没有变化。还是17。
编辑2:
正如John Bollinger在下面正确指出的那样,该代码没有任何作用,因为缓冲到nextWord中的字符串已经具有结尾的标点符号,并且该代码只会添加更多内容。我这是错误的想法。
最佳答案
说命令时您不正确...
$ grep -o -w 'Mars' TripToMars.txt | wc -w
...“仅将“火星”的实例查找为独立词”,或者至少该陈述在上下文中具有误导性。该命令查找不属于较大单词的“火星”实例,其中“单词”定义为字母,数字和/或下划线的连续字符串。特别是,它将与“火星”匹配,后跟一个标点符号,该标点符号与您似乎声称的内容相冲突。
但是您的两种扫描方法有什么区别?好吧,这...
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"
进行比较时,后者会错过去火星。
和
名字“火星”
和
火星上有水吗?
因为比较中包含了相邻的标点符号。您的文本很可能具有许多类似于这些结构的构造,并且您的
grep
命令没有进行其他演示。