首页 > 解决方案 > C - 使用 fgets() 填充通过循环迭代的结构数组。如何在同一行打印值?

问题描述

我在 C 中乱搞,试图了解它是如何工作的,但我遇到了一个问题。我有一个用两个字符数组变量定义的结构。我正在使用键盘输入中的 fgets() 填充它们。但是,当我去打印时,输出如下所示:

Gibson
Les Paul
Fender
Stratocaster

当我真的希望它看起来像这样时:

Gibson Les Paul
Fender Stratocaster

当我使用scanf而不是fgets时,我可以很好地完成这一点,但我想我会看看我是否可以理解为什么会发生这种情况,因为我是C新手。

这是我的代码:

#include <stdio.h>

typedef struct Guitars
{ 
    char brand[10];
    char model[10];
} input;

void input_data(struct Guitars input[10])
{
    for(int i=0; i<2; i++)
    {
        printf("Please enter the brand: ");
        fgets(input[i].brand, 10, stdin);
        printf("Please enter the model: ");
        fgets(input[i].model, 10, stdin);
    }
}

void print_array(struct Guitars input[10])
{
    for(int i=0; i<2; i++) 
    {
        printf("%s%s", input[i].brand, &input[i].model);
    }   
}

int main(void) {
    struct Guitars input[10];
    input_data(input);
    print_array(input);
}

谢谢你的帮助!

标签: carraysstructurefgets

解决方案


太大了,无法放在一条评论中。

确保既不.brand也不.model包含换行符(但不要使用gets(): 请参阅Why gets()is too dangerous to be used — ever!)。请记住,fgets()其中包括换行符(如果它适合缓冲区)。您可以使用以下方法将其删除:

if (fgets(buffer, sizeof(buffer), stdin) != 0)
{
    buffer[strcspn(buffer, "\n")] = '\0';
    …
}

然后使用:

printf("%s %s\n", input[i].brand, input[i].model);

请注意%s转换规范和末尾的换行符之间的空格。如果需要,您可以使用冒号或破折号或类似的东西使品牌和型号之间的分隔更清晰。

原评论结束。

另外,请注意,Stratocaster它不适合 10 个数组。您的结构需要更大的数组来存储样本数据。您还需要考虑在数组中创建了多少条目——您已经硬连线了 2,这有点限制。

将这些更改放在一起会产生如下代码:

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

struct Guitars
{
    char brand[20];
    char model[20];
};

static int input_data(int max_entries, struct Guitars input[])
{
    int i;
    for (i = 0; i < max_entries; i++)
    {
        printf("Please enter the brand: ");
        if (fgets(input[i].brand, sizeof(input[i].brand), stdin) == 0)
        {
            fprintf(stderr, "Unexpected EOF\n");
            break;
        }
        input[i].brand[strcspn(input[i].brand, "\n")] = '\0';
        printf("Please enter the model: ");
        if (fgets(input[i].model, sizeof(input[i].model), stdin) == 0)
        {
            fprintf(stderr, "Unexpected EOF\n");
            break;
        }
        input[i].model[strcspn(input[i].model, "\n")] = '\0';
    }
    return i;
}

static void print_array(int num_entries, struct Guitars input[])
{
    for (int i = 0; i < num_entries; i++)
    {
        printf("%s %s\n", input[i].brand, input[i].model);
    }
}

int main(void)
{
    struct Guitars input[10];
    int n = input_data(10, input);
    print_array(n, input);
    return 0;
}

示例运行:

Please enter the brand: Gibson
Please enter the model: Les Paul
Please enter the brand: Fender
Please enter the model: Stratocaster
Please enter the brand: Unexpected EOF
Gibson Les Paul
Fender Stratocaster

您很容易争辩说“意外的 EOF”消息不适合第一个(品牌)输入;第二个(模型)输入更令人信服。修改代码以满足您的需求很容易。


推荐阅读