이번 편의 목표: 제목과 연체 일수를 명령으로 받아 CSV에 남기고, 권마다 연체료를 출력합니다.
앞 편의 구조체, 슬라이스, 오류, 파일, 명령행을 한 프로그램으로 모읍니다. 기록 파일 이름은 loans.csv입니다. 한 줄이 책 한 권이고, 제목과 일수를 쉼표로 구분합니다. 제목에는 쉼표를 넣지 않습니다.
main.go를 다음으로 바꿉니다. 11편의 book 패키지를 import하지 않으면 실행에 포함되지 않습니다. 계산은 이 파일의 overdueFee를 씁니다.
package main
import (
"fmt"
"os"
"strconv"
"strings"
)
type Loan struct {
Title string
Days int
}
func overdueFee(days int) int {
if days <= 0 {
return 0
}
return days * 100
}
func parseLoan(line string) (Loan, bool) {
line = strings.TrimSpace(line)
if line == "" {
return Loan{}, false
}
parts := strings.Split(line, ",")
if len(parts) != 2 {
return Loan{}, false
}
title := strings.TrimSpace(parts[0])
days, err := strconv.Atoi(strings.TrimSpace(parts[1]))
if err != nil || title == "" || days < 0 {
return Loan{}, false
}
return Loan{Title: title, Days: days}, true
}
func load(path string) []Loan {
text, err := os.ReadFile(path)
if err != nil {
return nil
}
var loans []Loan
for _, line := range strings.Split(string(text), "\n") {
loan, ok := parseLoan(line)
if ok {
loans = append(loans, loan)
}
}
return loans
}
func save(path string, loans []Loan) error {
var body strings.Builder
for _, loan := range loans {
fmt.Fprintf(&body, "%s,%d\n", loan.Title, loan.Days)
}
return os.WriteFile(path, []byte(body.String()), 0644)
}
func main() {
path := "loans.csv"
loans := load(path)
args := os.Args[1:]
if len(args) == 0 || args[0] == "list" {
if len(loans) == 0 {
fmt.Println("기록이 없습니다.")
}
for _, loan := range loans {
fmt.Printf("%s %d일 %d원\n", loan.Title, loan.Days, overdueFee(loan.Days))
}
return
}
if args[0] != "add" || len(args) < 3 {
fmt.Println("사용법: go run . add 제목 연체일수")
return
}
days, err := strconv.Atoi(args[2])
if err != nil || args[1] == "" || days < 0 {
fmt.Println("사용법: go run . add 제목 연체일수")
return
}
loans = append(loans, Loan{Title: args[1], Days: days})
if err := save(path, loans); err != nil {
fmt.Println(err)
return
}
fmt.Println("기록했습니다.")
}파일이 없으면 load는 빈 목록으로 시작합니다. 잘못된 줄은 건너뜁니다. add는 목록 끝에 한 권을 붙인 뒤 파일 전체를 다시 씁니다. list와 인자가 없는 실행은 저장된 권을 출력합니다.
go run .
기록이 없습니다.
go run . add 생각나무 3
기록했습니다.
go run . list
생각나무 3일 300원
일수가 정수가 아니거나 음수이면 사용법만 출력하고 파일은 바꾸지 않습니다.
직접 해 보기
go run . add 도서관 2 를 실행한 뒤 list를 보세요. 둘째 줄은 도서관 2일 200원이어야 합니다.
해설
하루 100원이고 2일이므로 200원입니다. loans.csv에는 생각나무,3과 도서관,2가 각각 한 줄로 남습니다. 목록 순서는 추가한 순서입니다.
COMMENTS
댓글 0
이 글에 대한 의견이나 질문을 남겨 주세요.
댓글은 구글이나 카카오로 시작한 뒤에 남길 수 있습니다.
등록된 댓글이 없습니다.