我正在尝试创建一个使用函数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;
}
我真的可以使用一些帮助!
答案 0 :(得分:4)
首先是一般建议:利用编译器抱怨的错误和警告!你应该能够以这种方式纠正许多基本错误。使用gcc
进行编译时,请使用标记-Wall
和-Wextra
作为额外警告。
例如,你应该得到像
这样的东西警告:传递'strcmp'的参数1使得指针来自整数而没有强制转换
确实,strcmp
和strlen
的论点应该是char
的指针。但是,您传递给他们的每个论点(argv[1]
除外)都是#{1}}类型。
使用我提到的char
标志,还应该有一个
警告:有符号和无符号整数表达式之间的比较
参考比较gcc
。实际上,i < (strlen(*buf) - N)
的结果是无符号的(类型为strlen
),如果结果小于size_t
,则可能会导致问题。它们的差异而不是负数将被视为无符号数,导致索引变量N
循环通过比预期更大的范围,并可能导致分段错误。解决方案是演员:i
。
另一个错误是第一次检查while条件时,i < ((int) strlen(*buf) - N)
未初始化。此外,此条件不会查找buffer
标记,而是查找4个字母的字符串EOF
。要检查您是否已到达文件末尾,可以使用"#EOF"
的返回值。即使您希望程序在新行上出现字符串fgets
时停止,您仍应考虑缓冲区可能包含"#EOF"
。
最后一个问题涉及“单词识别”。调试后,您当前的代码会在遇到单词"#EOF\n"
时计算单词"hi"
的外观。这是理想的行为吗?