【问题标题】:What am I missing in this use of fgets?我在使用 fgets 时缺少什么?
【发布时间】:2018-10-13 14:58:09
【问题描述】:

如果我用 scanf 运行下面的代码,如果它在轨道数组中,它会返回一个字符串。根据 Head First C 一书,这应该与 fgets 一起使用,但对我没有任何回报:

#include <stdio.h>
#include <string.h>

#define MAX 80

char tracks[][MAX] = {
    "The Girl from Ipanema",
    "Here Comes the Sun",
    "Wonderwall",
    "You Belong To Me",
    "Everlong",
};

void find_track(char search_for[])
{
    int i = 0;
    for(i = 0; i < 5; i++) {
        if(strstr(tracks[i], search_for)) {
            printf("Track %d: %s\n", i, tracks[i]);
        }
    }
}

int main()
{
    char search_for[MAX];
    printf("Search for: ");
    //scanf("%79s", search_for);
    fgets(search_for, MAX, stdin);
    find_track(search_for);
    return 0;
}

输入如下所示:

./tracks
Search for: 
Here

什么都没发生

【问题讨论】:

  • 发布您提供的准确输入。

标签: c scanf fgets


【解决方案1】:

这可能是因为fgets 也会读取换行符,即'\n'。更详细的:

如果您键入Girl&lt;enter&gt;,则search_for 将包含以下字符:'G' 'i' 'r' 'l' '\n' 但是,您的tracks 仅包含'G' 'i' 'r' 'l',而没有'\n'

因此,您将找不到匹配的子字符串。

尝试改变:

fgets(search_for, MAX, stdin);

进入

fgets(search_for, MAX, stdin);
if (strlen(search_for) > 0) search_for[strlen(search_for)-1] = '\0';

删除尾随的换行符

基于 cmets 编辑

确实(取决于您的操作系统/环境)输入流可以在没有换行符的情况下终止(在某些系统上为 ctrl-z、ctrl-d)。如果这样做,上面的代码是不够的。它需要额外的检查,例如:

if (strlen(search_for) > 0 && search_for[strlen(search_for)-1] == '\n')
    search_for[strlen(search_for)-1] = '\0';

确保只有“换行符”转换为字符串终止符。

【讨论】:

【解决方案2】:

你也可以使用函数 memcpy 来去掉换行符。

C 库函数 void *memcpy(void *str1, const void *str2, size_t n) 将 n 个字符从内存区 str2 复制到内存区 str1。

fgets(s, MAX, stdin);  
memcpy(search_for, s, strlen(s)-1);    
find_track(search_for);

您也可以添加一些错误处理。

【讨论】:

    猜你喜欢
    • 2011-08-06
    • 1970-01-01
    • 2011-01-29
    • 1970-01-01
    • 2011-08-08
    • 1970-01-01
    • 2012-10-01
    • 2010-10-29
    相关资源
    最近更新 更多