C - использование fgets () для заполнения структурного массива, повторяемого в цикле.Как напечатать значения в одной строке? - PullRequest
0 голосов
/ 03 марта 2019

Я бездельничаю в 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);
}

Спасибоза любую помощь!

1 Ответ

0 голосов
/ 03 марта 2019

Слишком большой, чтобы поместиться в одном комментарии.

Убедитесь, что ни .brand, ни .model не содержат символ новой строки (но не используйте gets(): см. Почему gets() слишком опасен для использования - когда-либо! ).Помните, что 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» не подходит для первого (фирменного) ввода;это более убедительно для второго (модельного) ввода.Код легко изменить в соответствии с вашими потребностями.

...