strstr() 和 fgets() 在《Head First C》一书中的演示中的问题


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 终止字符串 - 这就是它意外工作的原因。

另一方面,scanfnstdin留下而不阅读它,所以这就是为什么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);
}

最新更新