在Head First C,第一版的书中,有这个程序:
#include <stdio.h>
#include <string.h>
char tracks[][80] = {
"I left my hearth 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++) {
if (strstr(tracks[i], search_for)) {
printf("Track %i: '%s'\n", i, tracks[i]);
}
}
}
int main() {
char search_for[80];
printf("Search for: ");
fgets(search_for, 80, stdin);
find_track(search_for);
return 0;
}
但是,在编译和测试时,您无法获得预期的结果。在打破了我的脑袋之后,我决定寻找fgets的文档,我发现该函数读取包含换行符,这就是为什么无论我搜索什么,我都得不到预期的结果。然而,在书中他们说该程序在测试时有效。这是一本书的错误,还是我错过了什么?
PS。使用scanf可以很容易地修复错误,一旦你知道程序为什么不能按预期工作就会变得很明显。
PS2。我记得C ++有一些语法来忽略换行符。 C有类似的东西吗?
答案 0 :(得分:4)
我也遇到了错误,但最新版本更正了错误。事实上,函数 CREATE PROCEDURE myproc()
BEGIN
DECLARE v1 INT DEFAULT 4;
WHILE v1 <= 94 DO
INSERT INTO `ostopd`.`identificationmandatorycheck`
(`Id`,
`UserId`,
`voterId`,
`passport`,
`CreatedOn`,
`CreatedBy`,
`UpdatedOn`,
`UpdatedBy`,
`Active`,
`Deleted`)
VALUES
(v1,v1,'O','O',CURRENT_TIMESTAMP,v1,NULL,NULL,0b1,0b0);
SET v1 = v1 + 1;
END WHILE;
END;
就像你说的那样。它只读取'char *fgets(char *s, int size, FILE *stream)
。如果遇到 null 字符('\ 0'),它只会将('\ 0')添加到缓冲区。因此,当我们使用函数size-1
时,由于find_track()
包含('\ 0'),我们无法获得任何内容。有一些解决方案可以处理它。
search_for
。请注意,不要只使用scanf("%79s", search_for)
,因为您会遇到与%s
相同的情况。fgets()
,它与前一个有一些区别。您可以避免空白问题的优势。PS:第一个,您可以添加新功能以避免出现空白问题。像这样:
scanf("%79[^\n]", search_for)
答案 1 :(得分:3)
你是对的;这确实是书中的一个错误。
我建议不要使用scanf
进行用户输入。它很难正确使用,错误检测非常重要(如果可能的话),并且无法进行错误恢复。
所有用户输入都应该先读取一行,然后再进行分析(例如使用strtol
或sscanf
)。读取一行可以使用fgets
完成,但遗憾的是,没有语法或功能可以忽略\n
。
你能做的是:
if (fgets(line, sizeof line, stdin)) {
line[strcspn(line, "\n")] = '\0'; // remove trailing '\n', if any
do_stuff_with(line);
}