]> git.lizzy.rs Git - rust.git/blob - src/doc/trpl/standard-input.md
Rollup merge of #21357 - kimroen:patch-1, r=sanxiyn
[rust.git] / src / doc / trpl / standard-input.md
1 % Standard Input
2
3 Getting input from the keyboard is pretty easy, but uses some things
4 we haven't seen before. Here's a simple program that reads some input,
5 and then prints it back out:
6
7 ```{rust,ignore}
8 fn main() {
9     println!("Type something!");
10
11     let input = std::io::stdin().read_line().ok().expect("Failed to read line");
12
13     println!("{}", input);
14 }
15 ```
16
17 Let's go over these chunks, one by one:
18
19 ```{rust,ignore}
20 std::io::stdin();
21 ```
22
23 This calls a function, `stdin()`, that lives inside the `std::io` module. As
24 you can imagine, everything in `std` is provided by Rust, the 'standard
25 library.' We'll talk more about the module system later.
26
27 Since writing the fully qualified name all the time is annoying, we can use
28 the `use` statement to import it in:
29
30 ```{rust}
31 use std::io::stdin;
32
33 stdin();
34 ```
35
36 However, it's considered better practice to not import individual functions, but
37 to import the module, and only use one level of qualification:
38
39 ```{rust}
40 use std::io;
41
42 io::stdin();
43 ```
44
45 Let's update our example to use this style:
46
47 ```{rust,ignore}
48 use std::io;
49
50 fn main() {
51     println!("Type something!");
52
53     let input = io::stdin().read_line().ok().expect("Failed to read line");
54
55     println!("{}", input);
56 }
57 ```
58
59 Next up:
60
61 ```{rust,ignore}
62 .read_line()
63 ```
64
65 The `read_line()` method can be called on the result of `stdin()` to return
66 a full line of input. Nice and easy.
67
68 ```{rust,ignore}
69 .ok().expect("Failed to read line");
70 ```
71
72 Do you remember this code?
73
74 ```{rust}
75 enum OptionalInt {
76     Value(i32),
77     Missing,
78 }
79
80 fn main() {
81     let x = OptionalInt::Value(5);
82     let y = OptionalInt::Missing;
83
84     match x {
85         OptionalInt::Value(n) => println!("x is {}", n),
86         OptionalInt::Missing => println!("x is missing!"),
87     }
88
89     match y {
90         OptionalInt::Value(n) => println!("y is {}", n),
91         OptionalInt::Missing => println!("y is missing!"),
92     }
93 }
94 ```
95
96 We had to match each time to see if we had a value or not. In this case,
97 though, we _know_ that `x` has a `Value`, but `match` forces us to handle
98 the `missing` case. This is what we want 99% of the time, but sometimes, we
99 know better than the compiler.
100
101 Likewise, `read_line()` does not return a line of input. It _might_ return a
102 line of input, though it might also fail to do so. This could happen if our program
103 isn't running in a terminal, but as part of a cron job, or some other context
104 where there's no standard input. Because of this, `read_line` returns a type
105 very similar to our `OptionalInt`: an `IoResult<T>`. We haven't talked about
106 `IoResult<T>` yet because it is the *generic* form of our `OptionalInt`.
107 Until then, you can think of it as being the same thing, just for any type –
108 not just `i32`s.
109
110 Rust provides a method on these `IoResult<T>`s called `ok()`, which does the
111 same thing as our `match` statement but assumes that we have a valid value.
112 We then call `expect()` on the result, which will terminate our program if we
113 don't have a valid value. In this case, if we can't get input, our program
114 doesn't work, so we're okay with that. In most cases, we would want to handle
115 the error case explicitly. `expect()` allows us to give an error message if
116 this crash happens.
117
118 We will cover the exact details of how all of this works later in the Guide.
119 For now, this gives you enough of a basic understanding to work with.
120
121 Back to the code we were working on! Here's a refresher:
122
123 ```{rust,ignore}
124 use std::io;
125
126 fn main() {
127     println!("Type something!");
128
129     let input = io::stdin().read_line().ok().expect("Failed to read line");
130
131     println!("{}", input);
132 }
133 ```
134
135 With long lines like this, Rust gives you some flexibility with the whitespace.
136 We _could_ write the example like this:
137
138 ```{rust,ignore}
139 use std::io;
140
141 fn main() {
142     println!("Type something!");
143
144     // here, we'll show the types at each step
145
146     let input = io::stdin() // std::io::stdio::StdinReader
147                   .read_line() // IoResult<String>
148                   .ok() // Option<String>
149                   .expect("Failed to read line"); // String
150
151     println!("{}", input);
152 }
153 ```
154
155 Sometimes, this makes things more readable – sometimes, less. Use your judgement
156 here.
157
158 That's all you need to get basic input from the standard input! It's not too
159 complicated, but there are a number of small parts.