我正在尝试创建一个使用函数 fgets()、strncmp() 和 strlen() 的 C 代码,主要是为了更好地理解它们。目标是使用 fgets() 输入文本,以文件结束标记将其关闭,并计算某个单词(在程序参数中设置)出现的次数。这是我到目前为止所得到的,但它对我不起作用。我在使用字符串和数组方面遇到了困难,因为我是一名初级 C 程序员。
int main(int argc, char *argv[])
{
int i, N, wrdcnt = 0;
char buf[1026], *eof = "#EOF";
N = strlen(argv[1]);
while (strcmp(*buf, *eof) != 0)
{
fgets(buf, 1025, stdin);
for (i = 0; i < (strlen(*buf) - N); i++)
{
if (strncmp(buf[i], argv[1], N) == 0)
{
wrdcnt++;
}
}
}
printf("%d", wrdcnt);
return 0;
}
我真的需要一些帮助!
最佳答案
首先,一般性建议:利用编译器提示的错误和警告!您应该能够通过这种方式纠正许多基本错误。当使用 gcc
编译时使用标志-Wall
和-Wextra
以获得额外警告。
例如,您应该得到类似的内容
warning: passing argument 1 of ‘strcmp’ makes pointer from integer without a cast
确实,strcmp
的论点和strlen
应该是指向char
的指针。但是,您传递给它们的每个参数( argv[1]
除外)的类型都是 char
。相反。
使用gcc
我提到的标志,还应该有一个
warning: comparison between signed and unsigned integer expressions
引用比较i < (strlen(*buf) - N)
。确实,strlen
的结果是无符号的(类型为 size_t
),如果其结果小于 N
,则可能会导致问题。它们的差值(而不是负数)将被视为无符号数,从而导致索引变量 i
循环的范围比您预期的范围大得多,并可能导致段错误。解决方案是强制转换:i < ((int) strlen(*buf) - N)
.
另一个错误是第一次检查 while 条件时,buffer
未初始化。此外,此条件不会查找 EOF
标记,但对于 4 个字母的字符串 "#EOF"
。要检查是否已到达文件末尾,可以使用返回值 fgets
反而。即使您希望程序在出现字符串 "#EOF"
时停止在新行中,您仍然应该考虑缓冲区可能包含 "#EOF\n"
相反。
最后一个问题涉及“单词识别”。您当前的代码在调试后会计算单词 "hi"
的出现次数。当它遇到单词"hill"
时。这是期望的行为吗?
关于C语言中的单词计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29309875/