이번 편의 목표: 제목과 연체 일수를 명령으로 받아 CSV에 남기고, 권마다 연체료를 출력합니다.
앞 편의 소유권, 구조체, Result, 벡터, 파일을 한 프로그램으로 모읍니다. 기록 파일 이름은 loans.csv입니다. 한 줄이 책 한 권이고, 제목과 일수를 쉼표로 구분합니다. 제목에는 쉼표를 넣지 않습니다.
src/main.rs를 다음으로 바꿉니다. 13편의 book.rs는 이 파일에 mod로 연결하지 않으면 실행에 포함되지 않습니다. 계산은 이 파일의 overdue_fee를 씁니다.
use std::env;
use std::fs;
use std::io;
struct Loan {
title: String,
days: i32,
}
fn overdue_fee(days: i32) -> i32 {
if days <= 0 { 0 } else { days * 100 }
}
fn parse_loan(line: &str) -> Option<Loan> {
let line = line.trim();
if line.is_empty() {
return None;
}
let mut parts = line.split(',');
let title = parts.next()?.trim();
let days: i32 = parts.next()?.trim().parse().ok()?;
if title.is_empty() || days < 0 {
return None;
}
Some(Loan {
title: title.to_string(),
days,
})
}
fn load(path: &str) -> Vec<Loan> {
let text = fs::read_to_string(path).unwrap_or_default();
let mut loans = Vec::new();
for line in text.lines() {
if let Some(loan) = parse_loan(line) {
loans.push(loan);
}
}
loans
}
fn save(path: &str, loans: &[Loan]) -> io::Result<()> {
let mut body = String::new();
for loan in loans {
body.push_str(&loan.title);
body.push(',');
body.push_str(&loan.days.to_string());
body.push('\n');
}
fs::write(path, body)
}
fn main() -> io::Result<()> {
let path = "loans.csv";
let mut loans = load(path);
let mut args = env::args().skip(1);
match args.next().as_deref() {
Some("add") => {
let title = args.next().unwrap_or_default();
let days: i32 = args.next().unwrap_or_default().parse().unwrap_or(-1);
if title.is_empty() || days < 0 {
println!("사용법: cargo run -- add 제목 연체일수");
return Ok(());
}
loans.push(Loan { title, days });
save(path, &loans)?;
println!("기록했습니다.");
}
Some("list") | None => {
if loans.is_empty() {
println!("기록이 없습니다.");
}
for loan in &loans {
println!("{} {}일 {}원", loan.title, loan.days, overdue_fee(loan.days));
}
}
Some(_) => {
println!("명령은 add 또는 list입니다.");
}
}
Ok(())
}파일이 없으면 load는 빈 목록으로 시작합니다. 잘못된 줄은 건너뜁니다. add는 목록 끝에 한 권을 붙인 뒤 파일 전체를 다시 씁니다. list와 인자가 없는 실행은 저장된 권을 출력합니다.
cargo run
기록이 없습니다.
cargo run -- add 생각나무 3
기록했습니다.
cargo run -- list
생각나무 3일 300원
cargo run -- 의 --는 그 뒤의 단어를 프로그램 인자로 넘기라는 표시입니다. add와 제목, 일수가 args로 들어옵니다. 일수가 정수가 아니거나 음수이면 사용법만 출력하고 파일은 바꾸지 않습니다.
직접 해 보기
cargo run -- add 도서관 2 를 실행한 뒤 list를 보세요. 둘째 줄은 도서관 2일 200원이어야 합니다.
해설
하루 100원이고 2일이므로 200원입니다. loans.csv에는 생각나무,3과 도서관,2가 각각 한 줄로 남습니다. 목록 순서는 추가한 순서입니다.
COMMENTS
댓글 0
이 글에 대한 의견이나 질문을 남겨 주세요.
댓글은 구글이나 카카오로 시작한 뒤에 남길 수 있습니다.
등록된 댓글이 없습니다.