C-Project13

‍우건우·2024년 2월 5일

*(part +i).on_hand == (part + i)->on_hand

인수 및 반환 값으로서의 구조체

#include<stdio.h>
#include<string.h>
#define NAME_LEN 20

typedef struct tagPart {
	int number;
	char name[NAME_LEN + 1];
	int on_hand;
}Part;

Part build_part(Part* part, int number, const char* name, int on_hand) {
	
	part->number = number;
	strcpy(part->name, name);
	part->on_hand = on_hand;
	//return p;
}

int main(void) {

	const char* partName = "cooler";
	//Part returned_part;
	//returned_part = build_part(2, partName, 10);
	Part part1;
	build_part(&part1, 2, partName, 10);

	return 0;
}

중첩 구조체
한 종류의 구조체를 다른 종류의 구조체 안에 내포하는 것을 중첩 구조체라고 부릅니다.
예를 들어, 사용자의 이름, 중간 이니셜 및 성을 저장할 수 있는 다음 구조체를 선언했다고 가정합시다.

#include<stdio.h>
#include<string.h>
#define FIRST_NAME_LEN 20
#define LAST_NAME_LEN 20

typedef struct person_name {
	char first_name[FIRST_NAME_LEN + 1];
	char middle_name;
	char last_name[LAST_NAME_LEN + 1];
}PersonName;

typedef struct student_info {
	PersonName name; //구조체 안에 구조체가 들어간 형태(중첩구조체)
	int id, age;
	char gender;
}StudentInfo;

int main(void) {

	StudentInfo stu1;

	stu1.id = 24001;
	stu1.age = 20;
	stu1.gender = 'M';
	strcpy(stu1.name.first_name, "Peter");
	stu1.name.middle_name = 'G';
	strcpy(stu1.name.last_name, "Hernadez");

	printf("id: %d\n", stu1.id);
	printf("age: %d\n", stu1.age);
	printf("gender: %c\n", stu1.gender);
	printf("Full name: %s %c %s\n", stu1.name.first_name,stu1.name.middle_name,
		stu1.name.last_name);

	return 0;
}

구조체 타입의 배열도 선언과 동시에 초기화 가능

#include<stdio.h>
#include<string.h>
#define NAME_LEN 20

typedef struct tagPart {
	int number;
	char name[NAME_LEN + 1];
	int on_hand;
}Part;

int main(void) {

	Part part1 = {
		1,
		"cable",
		10
	};

	Part partArr[3] = {
		{2,"case",5},
		{3,"printer",10},
		{4,"harddisk",8}
	};
	
	return 0;
}

부품 프로그램

  • 부품추가(insert) : 새 부품 번호, 부품이름 및 보유수량을 입력받아서 데이터 베이스에 추가
    데이터베이스에 이미 해당 번호의 부품이 있으면 오류 처리.
    데이터베이스에 저장가능한 공간이 가득 찼으면 오류 처리.
  • 부품번호 입력시 정보출력(search) : 부품 번호를 지정하면 부품 이름과 현재 보유 수량을 인쇄합니다.
    부품 번호가 현재 데이터베이스에 없으면 오류처리
  • 특정 부품의 보유 수량을 변경(update) : 부품 번호를 지정하면 변경할 수량을 입력받아서 데이터베이스 갱신. 해당 부품 번호가 없으면 오류처리
  • 모든 부품 정보를 출력(print) : 부품은 입력된 순서대로 표시
  • 프로그램 종료(quit)
    실행 형태 :
    작업을 위해서 명령을 입력받으며 i(삽입), s(검색), u(업데이트), p(인쇄), q(종료)

inventory.c

#include<stdio.h>
#include "inventory.h"
#include "read_line.h"

void insert(Part* database, int* num_part)
{
	//부품 번호를 입력받을 변수
	int part_number;

	if (*num_part == MAX_PARTS) {
		printf("Database is full: can't add more parts\n");
		return;
	}
	printf("Enter part number: ");
	scanf_s("%d", &part_number);
	//입력 받은 새로운 부품 번호가 데이터 베이스에 이미 있는지 체크
	if (find_part(database, *num_part, part_number) >= 0) {
		//find_part 리턴 값이 0보다 크거나 같다는 것은 추가할 부품번호와 같은 부품을 찾았다는 의미

		printf("Part already exists.\n");
		return;
	}
	database[*num_part].number = part_number;
	printf("Enter part name: ");
	read_line(database[*num_part].name, NAME_LEN);
	printf("Enter quantity on hand: ");
	scanf("%d", &database[*num_part].on_hand);

	(*num_part)++;
}

void search(Part* database, int* num_part)
{
	int i, number;
	printf("Enter part number: ");
	scanf("%d", &number);
	i = find_part(database, *num_part, number);

	if (i >= 0) {//조건이 참이라면 해당 번호의 부품이 데이터베이스에 있다는 의미
		printf("Part name: %s\n", database[i].name);
		printf("Quatity on hand: %d\n", database[i].on_hand);
	}
	else {//데이터 베이스에 찾는 번호의 부품이 없는 경우
		printf("Part not found\n");
	}
}

void update(Part* database, int* num_part)
{
	int i, number, change;
	printf("Enter part number: ");
	scanf("%d", &number);
	i = find_part(database, *num_part, number);

	if (i >= 0) {//부품이 데이터 베이스에 있는 경우
		printf("Enter change in quantity on hand: ");
		scanf("%d", &change);
		database[i].on_hand += change;
	}
	else {//입력한 부품번호에 해당하는 부품이 데이터 베이스에 없는 경우
		printf("Part not found.\n");
	}
}

void print(Part* database, int* num_part)
{
	int i;
	printf("Part Number Part Name");

	for (i = 0; i < *num_part; i++)
		printf("%7d%12s%11d\n", database[i].number, database[i].name, database[i].on_hand);
}

int find_part(Part* database, int* num_part, int number) {
	int i;
	for (i = 0; i < *num_part; i++)
		if ((database + i)->number == number)
			return i;//찾은 경우 찾은 인덱스를 반환
	return -1;//못찾은 경우
}

read_line.h

#pragma once
#include <stdio.h>
#include <ctype.h>
#include "read_line.h"

int read_line(char str[], int n) {

	int ch, i = 0;
	while (isspace(ch = getchar()))
		;
	while (ch != '\n' && ch != EOF) {
		if (i < n)
			str[i++] = ch;
		ch = getchar();
	}
	str[i] = '\0';
	
	return i;
}

inventory.h

#pragma once //인클루드를 한번만 허용(
#define NAME_LEN 20
#define MAX_PARTS 100
/*
중복 포함을 방지하는 이전 방식
#ifndef __INVENTORY_H__
#define __INVENTORY_H__

#endif
*/

typedef struct part {
	int number;
	char name[NAME_LEN + 1];
	int on_hand;
}Part;

void insert(Part* database, int* num_parts);
void search(Part* database, int* num_parts);
void update(Part* database, int* num_parts);
void print(Part* database, int* num_parts);

int find_part(Part* database,int* num_part, int number);//프로그램에서 사용하기 위한 헬퍼 함수 선언

Filename.c

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

Part inventory[MAX_PARTS]; //전역변수로 데이터 베이스로 사용될 배열

int main(void) {

	int num_parts = 0;//현재 보유중인 부품 갯수를 카운팅할 전역변수
	char code;
	for (;;) {
		printf("Enter operation code: ");
		scanf_s("%c", &code);

		switch (code) {
		case 'i':
			insert(inventory, &num_parts);
			break;

		case 's':
			search(inventory, &num_parts);
			break;
		case 'u':
			update(inventory, &num_parts);
			break;
		case 'p':
			print(inventory, &num_parts);
			break;
		case 'q':
			return 0;
		default:
			printf("Illegal code\n");

		}
		while (getchar() != '\n')
			;
		printf("\n");
	}
	
	return 0;
}

0개의 댓글