Заменить повторяющийся код C

В данном файле есть повторяющиеся строки (одного и того же) кода.

#include <stdio.h>

#include "contacts.h"

void getName(struct Name *name) {

    char yesNo;

    printf("Please enter the contact's first name: ");
    scanf("%30[^\n]%*c", name->firstName);

    printf("Do you want to enter a middle initial(s)? (y or n): ");
    scanf("%c%*c", &yesNo);

    if (yesNo == 'y' || yesNo == 'Y') {
        printf("Please enter the contact's middle initial(s): ");
        scanf("%6[^\n]%*c", name->middleInitial);
    }

    printf("Please enter the contact's last name: ");
    scanf("%35[^\n]%*c", name->lastName);
}

void getAddress(struct Address *address)
{
    char yesNo;

    do {
        printf("Please enter the contact's street number: ");
        scanf("%d%*c", &address->streetNumber);
    } while (address->streetNumber < 1);

    printf("Please enter the contact's street name: ");
    scanf("%40[^\n]%*c", address->street);

    printf("Do you want to enter an apartment number? (y or n): ");
    scanf("%c%*c", &yesNo);

    if (yesNo == 'y' || yesNo == 'Y') {
        do {
            printf("Please enter the contact's apartment number: ");
            scanf("%d%*c", &address->apartmentNumber);
        } while (address->apartmentNumber < 1);
    }

    printf("Please enter the contact's postal code: ");
    scanf("%7[^\n]%*c", address->postalCode);

    printf("Please enter the contact's city: ");
    scanf("%40[^\n]%*c", address->city);
}

void getNumbers(struct Numbers *numbers)
{
    char yesNo;

    printf("Do you want to enter a cell phone number? (y or n): ");
    scanf("%c%*c", &yesNo);

    if (yesNo == 'y' || yesNo == 'Y') {
        printf("Please enter the contact's cell phone number: ");
        scanf("%10[^\n]%*c", numbers->cell);
    }

    printf("Do you want to enter a home phone number? (y or n): ");
    scanf("%c%*c", &yesNo);

    if (yesNo == 'y' || yesNo == 'Y') {
        printf("Please enter the contact's home phone number: ");
        scanf("%10[^\n]%*c", numbers->home);
    }

    printf("Do you want to enter a business phone number? (y or n): ");
    scanf("%c%*c", &yesNo);

    if (yesNo == 'y' || yesNo == 'Y') {
        printf("Please enter the contact's business phone number: ");
        scanf("%10[^\n]%*c", numbers->business);
    }
}

Эти повторяющиеся строки нужно заменить на одну функцию, т.е. написать функцию где эти строки будут заменены (сделать так, чтобы не было "повторения"). Я очень долго думал над этим заданием и подумал заменить вопросы с ответом yesNo, но так и не получилось (показалось очень плохой идеей).

Потом в void getNumbers увидел, что повторяется строка scanf("%10[^\n]%*c", numbers->...); и заменить это в отдельной функции (опять же, чтобы не писать ее столько раз в getNumbers) показалось намного лучшей идеей, но пока что пытался сделать - не получилось.

Нужна помощь. Если не написать функцию, хотябы намекнуть как я ее могу написать, потому что идей пока нет. Заранее спасибо.


Ответы (1 шт):

Автор решения: Zhihar

если вы про связку printf, scanf, то что мешает сделать

void getData(const char* output, const char* format, void* input) {
    printf(output);
    scanf(format, input);
}

тогда код будет выглядеть так:

void getName(struct Name *name) {

    char yesNo;

    getData("Please enter the contact's first name: ", "%30[^\n]%*c", name->firstName);

    getData("Do you want to enter a middle initial(s)? (y or n): ", "%c%*c", &yesNo);

    if (yesNo == 'y' || yesNo == 'Y')
        getData("Please enter the contact's middle initial(s): ", "%6[^\n]%*c", name->middleInitial);

    getData("Please enter the contact's last name: ", "%35[^\n]%*c", name->lastName);
}

хоть чуть-чуть, а короче :)

P.S.

кстати связку

if (yesNo == 'y' || yesNo == 'Y') {...}

тоже можно обернуть во что-то типа:

bool isYesNo(const char answer) {
    return (yesNo == 'y' || yesNo == 'Y');
}

тогда и вызов будет поприятнее

if (isYesNo(yesNo)) {...}
→ Ссылка