# Feature Request: \`scan!\` macro

**URL:** <https://internals.rust-lang.org/t/feature-request-scan-macro/21027>\
**Category:** language design\
**Created:** [June 13, 2024, 2:41pm UTC](https://internals.rust-lang.org/t/feature-request-scan-macro/21027 "2024-06-13T14:41:56Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![jvcmarcenes](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jvcmarcenes/32/11971_2.png) [@jvcmarcenes](https://internals.rust-lang.org/u/jvcmarcenes)\
**Post date:** [June 13, 2024, 2:41pm UTC](https://internals.rust-lang.org/t/feature-request-scan-macro/21027/1 "2024-06-13T14:41:56Z")

</div>

Recently a friend of mine who mostly codes i Java and javascript asked me to teach him Rust. To practice we'd make some simple programs like a number guessing game. But I wanted to introduce the language incrementally, without introducing a concept without explaining it before and telling them to just _not worry about it_, _we'll talk about it later_...

However, getting input from stdin involves _many_ concepts from the language. If I were to write an expression to read a value from stdin, i'd probably write

```rust
{
    let mut buf = String::new();
    std::io::stdin().read_line(&mut buf).unwrap();
    buf.parse::<T>().unwrap()
}

```

This has a block expression, a mutable variable, the associated function `String::new`, modules and paths, mutable references, the `Result` enum, and a generic function.

While making the small number guessing game, I had to write this into a function and just say "you'll understand it later", it terrified them.

reading from stdin is a common thing to want to do, especially if you're playing around with a language to see how it works. I think a `scan!` macro that does that would be a great addition that would help minimize some of the learning curve and remove stigma around rust

a `scan!` macro feels as natural as `println!`

as to how it works, i dont have a design. probably something that crashes on io errors and evaluates to the result of the `str::parse` call?

```rust
let input: Result<i32, <i32 as FromStr>::Error> = scan!();
let input: Result<i32, _> = scan!();
let input = scan!(i32);

```

---

<div class="post-metadata">

**Author:** ![jdahlstrom](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jdahlstrom/32/3351_2.png) [@jdahlstrom](https://internals.rust-lang.org/u/jdahlstrom)\
**Post date:** [June 13, 2024, 2:57pm UTC](https://internals.rust-lang.org/t/feature-request-scan-macro/21027/2 "2024-06-13T14:57:18Z")

</div>

Suggestions to add full `scanf`-like machinery have not been very favorably received in the past, but there absolutely should at the very least be a simple, beginner-friendly way to read single numbers from input. This is a real problem in how teachable and approachable Rust is and, as an aside, has also been one of the biggest issues in using Java as a teaching language.

Rust is a very command-line-oriented language, there's no way to e.g. conjure a dialog to ask the user for input, so at the very least there should be a simple, robust way to read numeric data from stdin.

---

<div class="post-metadata">

**Author:** ![DanielKeep](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/danielkeep/32/1332_2.png) [@DanielKeep](https://internals.rust-lang.org/u/DanielKeep)\
**Post date:** [June 13, 2024, 3:23pm UTC](https://internals.rust-lang.org/t/feature-request-scan-macro/21027/3 "2024-06-13T15:23:11Z")

</div>

As someone who wrote a crate for doing approximately this a long time ago, a few quick thoughts.

First, what you describe should be `scanln!`, since it eats an entire line of input at a time. You can't avoid this, because `FromStr` has no ability to consume only part of its input. Also, given what it expands to, perhaps `parseln!` would be better.

And that will be pretty much limited to single values on a line, or a full line as a string, which means anyone trying to port even very simple `sscanf` code is going to immediately run into problems.

I feel like if you want something simple, a `read_line` or `readln` function/macro that _just_ gives you a line of text makes more sense. Yes, you still have to parse the value from that, but at least the operation of it is clear.

I also don't feel like a "simple" `scan!` macro is really possible. When I worked on mine, I immediately got stuck trying to figure out how to handle all the various ways of splitting up the input, handling groups and repetitions, different representations, _etc._\[1\] And these were all concerns I had to address to make something that felt meaningfully more useful than just doing `read_line().split().parse()` (or the nearest compilable equivalent).

If there was a single, clear "winner" among the third party crates, you could consider including that. But insofar as I'm aware, there isn't one.

Still, I do agree that improvement in this area would be a good thing.

* * *

1. It doesn't help that I got sucked into trying to make it look like `macro_rules!`/`match`, since it felt like it made sense to keep the syntax and capabilities vaguely compatible.

---

<div class="post-metadata">

**Author:** ![jvcmarcenes](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jvcmarcenes/32/11971_2.png) [@jvcmarcenes](https://internals.rust-lang.org/u/jvcmarcenes)\
**Post date:** [June 13, 2024, 6:02pm UTC](https://internals.rust-lang.org/t/feature-request-scan-macro/21027/4 "2024-06-13T18:02:09Z")

</div>

Maybe `scan` is a bad name. I think we just need a simpler way to get input, all the machinery for doing scanf-like "formatted scanning" seems like total overengineering for what should just be _read stdin and parse to a type_

If the developer wants to do formatted parsing of that input, he can do it himself, it doesn't need to be builtin into the macro

would `input!` be a better name?

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [June 13, 2024, 6:23pm UTC](https://internals.rust-lang.org/t/feature-request-scan-macro/21027/5 "2024-06-13T18:23:40Z")

</div>

Previous conversation:

> <https://github.com/rust-lang/rfcs/pull/3196>
>
> I think the best way to drive the addition of this function forward is to have a… dedicated RFC for it.
> 
> \[Rendered\](https://github.com/rust-lang/rfcs/blob/126e2bd1f6853ec2701cc041104917640f94bb2f/text/3196-inputln.md#readme)
> 
> Previous discussions:
> 
> \* https://github.com/rust-lang/rust/pull/75435
> \* https://github.com/rust-lang/rfcs/pull/3183 (related RFC that additionally proposes scan macros)

---

<div class="post-metadata">

**Author:** ![mdHMUpeyf8yluPfXI](https://avatars.discourse-cdn.com/v4/letter/m/58f4c7/32.png) [@mdHMUpeyf8yluPfXI](https://internals.rust-lang.org/u/mdHMUpeyf8yluPfXI)\
**Post date:** [June 13, 2024, 6:38pm UTC](https://internals.rust-lang.org/t/feature-request-scan-macro/21027/6 "2024-06-13T18:38:08Z")

</div>

The rust code is not more difficult than

```java
public class Main {
  public static void main(){
    Scanner s = new Scanner(System.in);
    int i = s.nextInt();
    // ...
  }
}

```

---

<div class="post-metadata">

**Author:** ![josh](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/josh/32/5934_2.png) [@josh](https://internals.rust-lang.org/u/josh)\
**Post date:** [June 13, 2024, 9:38pm UTC](https://internals.rust-lang.org/t/feature-request-scan-macro/21027/7 "2024-06-13T21:38:13Z")

</div>

cc @PO8, who is also interested in working on `inputln`.

---

<div class="post-metadata">

**Author:** ![PO8](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/po8/32/5588_2.png) [@PO8](https://internals.rust-lang.org/u/PO8)\
**Post date:** [July 6, 2024, 9:47pm UTC](https://internals.rust-lang.org/t/feature-request-scan-macro/21027/8 "2024-07-06T21:47:28Z")

</div>

Sorry I missed this earlier. I don't think any `scan!()` will be a part of the Input RFC, but a separate RFC would make sense. There's a lot of interesting semantics to resolve, which if done wrong is part of what makes C `scanf()` so terrible. In particular, handling of whitespace and "noise characters" becomes problematic.

This little snippet of crufty, undocumented code is what I used in the past for this kind of thing with AdventOfCode [libaoc/reparse/reparse.rs at main · BartMassey/libaoc · GitHub](https://github.com/BartMassey/libaoc/blob/main/reparse/reparse.rs) . I like a regex-based solution more than some arbitrary semantics, but it definitely isn't easier to use.

---

<div class="post-metadata">

**Author:** ![jvcmarcenes](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jvcmarcenes/32/11971_2.png) [@jvcmarcenes](https://internals.rust-lang.org/u/jvcmarcenes)\
**Post date:** [July 11, 2024, 10:07pm UTC](https://internals.rust-lang.org/t/feature-request-scan-macro/21027/9 "2024-07-11T22:07:12Z")

</div>

I don't think a `input` function/macro should also concern itself with parsing... why would we expect that?

Why not just a simple way to get what has been inputted in stdin? then let the user do the necessary parsing

---

<div class="post-metadata">

**Author:** ![jdahlstrom](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jdahlstrom/32/3351_2.png) [@jdahlstrom](https://internals.rust-lang.org/u/jdahlstrom)\
**Post date:** [July 12, 2024, 5:21am UTC](https://internals.rust-lang.org/t/feature-request-scan-macro/21027/10 "2024-07-12T05:21:42Z")

</div>

Why would we expect a `print` macro to also concern itself with formatting?

---

<div class="post-metadata">

**Author:** ![jvcmarcenes](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jvcmarcenes/32/11971_2.png) [@jvcmarcenes](https://internals.rust-lang.org/u/jvcmarcenes)\
**Post date:** [July 12, 2024, 9:35pm UTC](https://internals.rust-lang.org/t/feature-request-scan-macro/21027/11 "2024-07-12T21:35:57Z")

</div>

> Why would we expect a `print` macro to also concern itself with formatting?

I agree that the symmetry is charming, but formatting and parsing are two VERY different processes.

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [October 10, 2024, 9:36pm UTC](https://internals.rust-lang.org/t/feature-request-scan-macro/21027/12 "2024-10-10T21:36:15Z")

</div>

Closed on October 10, 2024, 9:36pm UTC

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
