【发布时间】:2015-03-27 19:42:21
【问题描述】:
我编写了一个程序,允许用户在任何文本文件中查找单词或单词集合的实例数。用户可以在命令行中输入如下内容:
$ ./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++;
}
生成 17 的代码让 Mars 尝试解释带有尾随标点符号的情况,但没有任何变化。还是 17 岁。
EDIT2:
正如 John Bollinger 在下面正确指出的那样,这段代码什么都不做,因为缓冲到 nextWord 中的字符串已经有尾随标点符号,并且代码只会添加更多。这是我的错误想法。
【问题讨论】:
-
不知道,但很容易找到。在每个
fscanf之后只需printf("%s\n",nextWord)。将输出重定向到几个文件并比较这些文件。 -
另外,在工作代码中,您可以使用此格式字符串
"%*[^a-zA-Z]%80[a-zA-Z]"将两个fscanf合并为一个。在我写这篇文章时,我突然想到你可能有缓冲区溢出。非工作代码中的格式字符串应为"%80s",以将字长限制为80。 -
感谢您的回复。对“%80s”的更改产生相同的结果
-
不,您不能安全地将两个
scanf()调用合二为一。当第一个编辑描述符与输入项不匹配时,结果行为会有所不同。 -
@JohnBollinger 好点,谢谢。
标签: c regex text scanf text-parsing