갈루아의 반서재

1.  반복문 만들기


현재까지는 정답을 맞출 때까지 질문이 이어지지 않고 1회성으로 끝난다. 이제 필요한 것은 이 과정을 반복작업으로 만드는 것이다. 아래를 보자.


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
extern crate rand;
 
use std::io;
use std::cmp::Ordering;
use rand::Rng;
 
fn main() {
    println!("Guess the number!");
 
    let secret_number = rand::thread_rng().gen_range(1101);
 
    println!("The secret number is: {}", secret_number);
 
    loop {
        println!("Please input your guess.");
 
        let mut guess = String::new();
 
        io::stdin().read_line(&mut guess)
            .expect("failed to read line");
 
        let guess: u32 = guess.trim().parse()
            .expect("Please type a number!");
 
        println!("You guessed: {}", guess);
 
        match guess.cmp(&secret_number) {
            Ordering::Less    => println!("Too small!"),
            Ordering::Greater => println!("Too big!"),
            Ordering::Equal   => println!("You win!"),
        }
    }
}
cs


앞서 만든 코드에서 Line 15 ~ Line 31 사이를 loop{ }를 통해 반복적으로 실행이 되도록 처리했다. 아래 실행화면을 보면, 정답을 맞춘 후 종료를 위해 quit 을 입력하는 등 숫자가 아닌 입력이 들어온 경우 처리에서 에러가 발생했다. 이에 대한 처리가 필요하다.

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
bourne@vikander MINGW64 ~/git/rust-projects/rust-projects/guessing_game (master)
$ cargo run
   Compiling guessing_game v0.1.0 (file:///C:/Users/vikander/git/rust-projects/rust-projects/guessing_game)
    Finished debug [unoptimized + debuginfo] target(s) in 0.32 secs
     Running `target\debug\guessing_game.exe`
Guess the number!
The secret number is: 19
Please input your guess.
84
You guessed: 84
Too big!
Please input your guess.
17
You guessed: 17
Too small!
Please input your guess.
19
You guessed: 19
You win!
Please input your guess.
quit
thread 'main' panicked at 'Please type a number!: ParseIntError { kind: InvalidDigit }', ../src/libcore\result.rs:788
note: Run with `RUST_BACKTRACE=1for a backtrace.
error: Process didn't exit successfully: `target\debug\guessing_game.exe` (exit code: 101)
cs



Line 32 의 break; 를 추가해서 정답을 맞춘 경우 loop 문을 나오도록 처리했다. 이 프로그램에서는 main( ) 함수가 마지막 함수이므로 이 상태로 프로그램 자체가 종료된다.


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
extern crate rand;
 
use std::io;
use std::cmp::Ordering;
use rand::Rng;
 
fn main() {
    println!("Guess the number!");
 
    let secret_number = rand::thread_rng().gen_range(1101);
 
    println!("The secret number is: {}", secret_number);
 
    loop {
        println!("Please input your guess.");
 
        let mut guess = String::new();
 
        io::stdin().read_line(&mut guess)
            .expect("failed to read line");
 
        let guess: u32 = guess.trim().parse()
            .expect("Please type a number!");
 
        println!("You guessed: {}", guess);
 
        match guess.cmp(&secret_number) {
            Ordering::Less    => println!("Too small!"),
            Ordering::Greater => println!("Too big!"),
            Ordering::Equal   => {
                println!("You win!");
                break;
            }
        }
    }
}
cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 
bourne@vikander MINGW64 ~/git/rust-projects/rust-projects/guessing_game (master)
$ cargo run
   Compiling guessing_game v0.1.0 (file:///C:/Users/vikander/git/rust-projects/rust-projects/guessing_game)
    Finished debug [unoptimized + debuginfo] target(s) in 0.32 secs
     Running `target\debug\guessing_game.exe`
Guess the number!
The secret number is: 13
Please input your guess.
18
You guessed: 18
Too big!
Please input your guess.
10
You guessed: 10
Too small!
Please input your guess.
13
You guessed: 13
You win!
 
cs


이제 남은 것은 숫자가 아닌 입력이 들어간 경우의 처리이다.

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
extern crate rand;
 
use std::io;
use std::cmp::Ordering;
use rand::Rng;
 
fn main() {
    println!("Guess the number!");
 
    let secret_number = rand::thread_rng().gen_range(1101);
 
    println!("The secret number is: {}", secret_number);
 
    loop {
        println!("Please input your guess.");
 
        let mut guess = String::new();
 
        io::stdin().read_line(&mut guess)
            .expect("failed to read line");
 
        let guess: u32 = match guess.trim().parse() {
            Ok(num) => num,
            Err(_) => continue,
        };
 
        println!("You guessed: {}", guess);
 
        match guess.cmp(&secret_number) {
            Ordering::Less    => println!("Too small!"),
            Ordering::Greater => println!("Too big!"),
            Ordering::Equal   => {
                println!("You win!");
                break;
            }
        }
    }
}
cs


Line 22~24

let guess: u32 = match guess.trim().parse() {
    Ok(num) => num,
    Err(_) => continue,
};
Ok 는 성공을 나타내고, Err는 실패를 나타낸다. 성공적으로 숫자로 파싱이 되었냐 아니냐로, 실패한 경우 반복문의 다음 문장으로 넘어가고 이 경우에는 계속해서 프로그램이 실행된다. 아래를 보자. 문자열이 입력되어도 계속해서 다음이 진행된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
bourne@vikander MINGW64 ~/git/rust-projects/rust-projects/guessing_game (master)
$ cargo run
    Finished debug [unoptimized + debuginfo] target(s) in 0.0 secs
     Running `target\debug\guessing_game.exe`
Guess the number!
The secret number is: 22
Please input your guess.
19
You guessed: 19
Too small!
Please input your guess.
23
You guessed: 23
Too big!
Please input your guess.
hj
Please input your guess.
22
You guessed: 22
You win!
 
cs


이제 마지막으로 필요한 것은 secret_number 를 숨기는 것이다. Line 12 를 주석처리한 모습이다.

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
extern crate rand;
 
use std::io;
use std::cmp::Ordering;
use rand::Rng;
 
fn main() {
    println!("Guess the number!");
 
    let secret_number = rand::thread_rng().gen_range(1101);
 
//    println!("The secret number is: {}", secret_number);
 
    loop {
        println!("Please input your guess.");
 
        let mut guess = String::new();
 
        io::stdin().read_line(&mut guess)
            .expect("failed to read line");
 
        let guess: u32 = match guess.trim().parse() {
            Ok(num) => num,
            Err(_) => continue,
        };
 
        println!("You guessed: {}", guess);
 
        match guess.cmp(&secret_number) {
            Ordering::Less    => println!("Too small!"),
            Ordering::Greater => println!("Too big!"),
            Ordering::Equal   => {
                println!("You win!");
                break;
            }
        }
    }
}
cs


완성된 모습이다.