char tracks[][80] = {
"I left my heart in Harvard Med School",
"Newark, Newark - a wonderful town",
"Dancing with a Dork",
"From here to maternity",
"The girl from Iwo Jima",
};
void find_track(char search_for[]) {
int i;
for (i = 0; i < 5; i++) {
char *pointer = strstr(tracks[i], search_for);
printf("P:%sn", pointer);
}
}
int main() {
char search_for[80];
printf("Search for: ");
fgets(search_for, 80, stdin);
// scanf("%79s", search_for);
find_track(search_for);
return 0;
}
这是使用 strstr(( 和 fgets(( 的一个例子。 但是当我运行它时,它无法返回匹配的指针,它始终为 null。
Search for: wonderful
P:(null)
P:(null)
P:(null)
P:(null)
P:(null)
我尝试了一些不同的表达方式: 1.I 将search_for阵列的容量从 80 减少到 10:
char search_for[10];
它有效!
Search for: wonderful
P:(null)
P:wonderful town
P:(null)
P:(null)
P:(null)
2.我用scanf((替换了函数fgets((。
scanf("%79s", search_for);
它也可以工作!
Search for: wonderful
P:(null)
P:wonderful town
P:(null)
P:(null)
P:(null)
因此,我对此感到困惑,谁能告诉我这种现象的深层原因?
这是因为fgets
最多读取长度 80-1 = 79 个字符(它留下 1 个字符,该字符变为空终止(,但在您键入"精彩"并按 Enter 后附加stdin
的换行符n
字符后停止读取。不过,它会将此n
字符复制到缓冲区,因此输入字符串实际上是"wonderfuln "
的,由于换行符,它与您拥有的数据不匹配。
现在,当您碰巧声明缓冲区大小为 10 时,fgets
没有空间来存储n
,但仍然 null 终止字符串 - 这就是它意外工作的原因。
另一方面,scanf
n
stdin
留下而不阅读它,所以这就是为什么scanf
也有效。但是,fgets
是更好,更安全的功能,因此您应该继续使用它。
快速解决方法是执行以下操作:
fgets(search_for, 80, stdin);
search_for[strlen(search_for)-1] = ' ';
find_track(search_for);
这会用空终止符覆盖n
。fgets 后,您在内存中"wonderfuln "
,然后search_for[strlen(search_for)-1] = ' ';
将其更改为"wonderful "
。
请注意,对于正确的程序,您还应该添加错误处理:
if(fgets(search_for, 80, stdin) != NULL)
{
search_for[strlen(search_for)-1] = ' ';
find_track(search_for);
}