2022.02.23 구조체를 활용하여 가족 신상을 입력 받아 출력하는 프로그램을 작성

2022. 2. 23. 19:32과제 업로드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#include <stdio.h>
#define FAMILY_MAX 4
 
 
//구조체 정의
struct MEMBER // 구성원 정보 구조체 정의
{
    char Name[20]; //구성원 이름을 담는 배열
    int Age; //구성원 나이 변수
    char PhoneNum[20]; // 구성원 휴대폰 번호를 문자열로 담는 배열
    int Rel; // 구성원 관계를 정의할 정수형 변수
};
 
struct FAMILY // 구성원 정보 구조체 정의
{
    struct MEMBER F_Mem[FAMILY_MAX];
    char F_Firstname[10]; //아버지 성을 담는 배열
    char M_Firstname[10]; //어머니 성을 담는 배열
};
//열거형 정의
enum RELATIONSHIP // 가족관계 열거형 정의
{
    FATHER, MOTHER, BROTHER, SISTER
}; //0,1,2,3 상수는 위의 내용과 순서대로 1대1 대응됩니다.
 
//사용자 정의 함수
 
//구성원 정보를 입력받는 함수
void input_Member_Info(int x, struct FAMILY* y)  // FAMILY 구조체 포인터 변수를 매개 변수로 받습니다. x는 반복문 사용 시 반복문 변수 i를 받는 매개 변수입니다. 
{
    //함수 입력시  FAMILY 구조체 포인터 변수 -> MEMBER 구조체 변수 F_Mem - > MEMBER 구조체 변수의 각 멤버 변수 순서로 참조합니다.  
    //scanf_s는 주소값을 입력해줘야 하는 것에 유의합니다. 문자열 출력 시 문자열,배열의 크기를 입력해줍니다.
 
    printf("%d번째 가족 신상을 입력합니다.\n", x + 1); //x+1로 1번째 부터 출력할 수 있도록 했습니다. 
    printf("가족관계를 선택하세요. Father(0) Mother(1) Brother(2) Sister(3) = "); // 가족관계를 정수형 데이터로 입력하도록 안내합니다.
    scanf_s("%d"&y->F_Mem[x].Rel); //정수형 데이터를 받아 FAMILY 구조체 포인터 변수 -> MEMBER 변수 F_Mem - > int Rel 로 참조하도록 설정했습니다. 
                                        //여기서 최종적으로는 int Rel 변수로 치환되기 때문에 &연산자를 붙여줍니다.
    printf("이름을 입력하세요 = ");
    scanf_s(" %s", y->F_Mem[x].Name, sizeof(y->F_Mem[x].Name)); //최종적으로 참조되는 곳이 배열이고 F_Mem[x].Name 가 배열이름으로 치환됩니다. 
                                                                //따라서 &연산자를 붙이지 않습니다.     
    printf("나이를 입력하세요 = ");
    scanf_s("%d"&y->F_Mem[x].Age); //최종 참조가 int Age이므로 &연산자를 사용합니다. 
    printf("전화번호를 입력하세요 = ");
    scanf_s(" %s", y->F_Mem[x].PhoneNum, sizeof(y->F_Mem[x].PhoneNum)); //최종 참조가 배열이고 배열이름으로 치환되므로 &연산자를 쓰지 않습니다.
 
}
 
//출력 양식을 출력하는 함수
void print_Form()
{
    printf("\n");
    printf("######################################\n");
    printf("관계\t성명\t나이\t전화번호\n"); //아래 구성원 정보와 줄을 맞추기 위해 \t 제어문자를 사용하여 정렬했습니다.
}
 
//구성원 정보 출력 함수
void print_Output(int x, struct FAMILY* y) // FAMILY 구조체 포인터 변수를 매개 변수로 받습니다. x는 반복문 사용 시 반복문 변수 i를 받는 매개 변수입니다. 
{
    //함수 출력시  FAMILY 구조체 포인터 변수 -> MEMBER 구조체 변수 F_Mem - > MEMBER 구조체 변수의 각 멤버 변수 순서로 참조합니다. 
    if (y->F_Mem[x].Rel == 1//구성원 관계를 정의하는 정수 Rel 이 1이면 어머님이기 때문에 아버지의 성을 받지 않습니다. 
    {
        printf("%s%s\t", y->M_Firstname, y->F_Mem[x].Name); 
        //문자열 서식문자 두개를 붙여 성과 이름을 출력합니다. 어머님이기 때문에 본인의 성을 그대로 사용합니다. 
    }
    else
    {
        printf("%s%s\t", y->F_Firstname, y->F_Mem[x].Name); 
        //문자열 서식문자 두개를 붙여 성과 이름을 출력합니다. 어머님이 아니면 모두 아버지의 성을 받아 사용합니다. 
    }
    printf("%d\t", y->F_Mem[x].Age); // MEMBER 구조체 멤버 변수 Age 까지 들어가서 값을 참조합니다.
    printf("%s\t", y->F_Mem[x].PhoneNum); // MEMBER 구조체 멤버 변수 Age 까지 들어가서 값을 참조합니다.
    printf("\n");
}
 
//구성원 관계 출력 함수
void print_Relation(int a) //매개 변수는 정수형을 받습니다. 이는 열거형 자료와 대응됩니다. 
{
    //switch 문을 사용하고 정수형 변수와 0,1,2,3과 매칭된 열거형 데이터를 이용해 구성원 관계를 출력합니다. 
    switch (a)
    {
    default:
        printf("UNKNOWN\t");
        break;
    case FATHER: // 0 과 대응됩니다.
        printf("Father\t");
        break;
    case MOTHER: // 1과 대응됩니다.
        printf("Mother\t");
        break;
    case BROTHER: // 2와 대응됩니다.
        printf("Brother\t");
        break;
    case SISTER: //3과 대응됩니다.
        printf("Sister\t");
        break;
    }
 
}
 
int main()
{
    //구조체 변수 선언
    struct FAMILY Family_F; //구성원 정보 구조체 변수 정의
 
    //열거형 변수 선언
    enum RELATIONSHIP Mem_Rel; // 구성원 가족관계 열거형 변수 정의 , 생략가능합니다. 
 
    //포인터 변수 선언
    struct FAMILY* ptr_Family;
    ptr_Family = &Family_F; //포인터 변수에 FAMILY 구조체 변수를 연결. ptr_Family는 중첩 구조체 변수 Family_F의 주소를 데이터로 갖습니다.  
                            //이는 구성원 정보 입력, 출력 함수에 인자로 사용됩니다. 
 
    //가족 성 입력
    printf("가족(아빠)의 성을 입력하세요 =");
    scanf_s("%s", Family_F.F_Firstname, sizeof(Family_F.F_Firstname));
     //Family_F.F_Firstname 는 FAMILY 구조체에서 배열이므로 &연산자를 쓰지 않습니다. &연산자를 써도 정상작동합니다. 그이유는 모르겠습니다.
    printf("가족(엄마)의 성을 입력하세요 =");
    scanf_s("%s", Family_F.M_Firstname, sizeof(Family_F.M_Firstname));
    //Family_F.M_Firstname 는 FAMILY 구조체에서 배열이므로 &연산자를 쓰지 않습니다. &연산자를 써도 정상작동합니다. 그이유는 모르겠습니다.
 
    for (int i = 0; i < FAMILY_MAX; i++
    //가족 구성원의 수만큼 구성원 정보 입력 함수를 반복실행합니다.
    {
        input_Member_Info(i, ptr_Family); 
        //시행횟수 i와 FAMILY구조체 포인터 변수 ptr_Family를 인자로 입력합니다.
    }
    
    //형식 출력
    print_Form();
 
    //구성원 정보 출력
    for (int i = 0; i < FAMILY_MAX; i++)
    {
        print_Relation(Family_F.F_Mem[i].Rel); 
        //FAMILY 구조체 변수의 멤버 변수인     MEMBER 구조체 변수 F_Mem의   멤버 변수 int Rel 을 인자로 받습니다. 
        //이는 구성원 관계 출력 함수에서 정수형 그대로 대입됩니다. 그렇기 때문에 열거형 변수를 선언해 사용안해도됩니다. 
        print_Output(i, ptr_Family); 
        //시행횟수 i와 FAMILY구조체 포인터 변수 ptr_Family를 인자로 입력합니다.
        printf("\n");
    }
 
    return 0;
 
}
cs