预订错误? (首先是C)

时间:2016-03-16 22:51:59

标签: c fgets

在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有类似的东西吗?

2 个答案:

答案 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进行用户输入。它很难正确使用,错误检测非常重要(如果可能的话),并且无法进行错误恢复。

所有用户输入都应该先读取一行,然后再进行分析(例如使用strtolsscanf)。读取一行可以使用fgets完成,但遗憾的是,没有语法或功能可以忽略\n

你能做的是:

if (fgets(line, sizeof line, stdin)) {
    line[strcspn(line, "\n")] = '\0';  // remove trailing '\n', if any
    do_stuff_with(line);
}