2016-09-27 5 views
1

단일 입력 줄에서 여러 정수를 읽는 간단한 프로그램으로 내 녹 스킬을 테스트하려고합니다. 그것은 올바르게 컴파일되지만 불행히도 1 2 3의 입력을 받으면 입력이 유효한 정수가 아니라고 패닉이 발생합니다. 누군가이 이유를 설명해 주시겠습니까? 또한 프로그램 수정 방법에 대한 설명을 제공 할 수 있습니까?정수 입력을 올바르게 읽지 못함

use std::io; 

fn main() { 
    let mut string = String::new(); 
    io::stdin().read_line(&mut string); 

    let int_vec: Vec<u32> = string.split(" ") 
     .map(|x| x.parse::<u32>().expect("Not an integer!")) 
     .collect(); 

    for i in (0..int_vec.len()).rev() { 
     print!("{} ", int_vec[i]); 
    } 
} 

답변

8

io::stdin().read_line(&mut String) 또한 유효한 정수하지 않은, "123\n"" "와 분할 후 마지막 STR의 원인이되는 문자열에 후행 개행 문자를 추가하기 때문입니다. 당신은이에 대한 str::trim()를 사용할 수 있습니다

use std::io; 

fn main() { 
    let mut string = String::new(); 
    io::stdin().read_line(&mut string); 

    let int_vec: Vec<u32> = string.trim() 
     .split(" ") 
     .map(|x| { 
      x.parse::<u32>() 
       .expect("Not an integer!") 
     }) 
     .collect(); 

    for i in (0..int_vec.len()).rev() { 
     print!("{} ", int_vec[i]); 
    } 
} 

을이 변경으로 프로그램이 작동합니다 또한

$ ./a 
1 2 3 
3 2 1 

, 당신은 당신의 for 루프를 단순화 할 수 있습니다 :

for i in int_vec.iter().rev() { 
    print!("{} ", i); 
} 
+0

감사합니다. 원래 문자열을 다듬 으려고했지만 함수가 새로운 문자열을 반환한다는 것을 잊었습니다. 이전 문자열을 조작하지 않습니다. 응답 해주셔서 감사합니다! –

+0

@KavanaughDempsey *이 함수는 새로운 문자열을 반환합니다 * - 구체적으로 말하면,'trim'은 새로운 * 문자열 slice *를 반환합니다 ('&str'); 이것은 기존 문자열을 참조하고 새로운 * 소유 문자열을 할당하지 않습니다 * ('String '). – Shepmaster

+0

'.trim(). split ("") 대신에'.split_whitespace()'도 고려해 볼 수 있습니다 .. – delnan

5

당신은 이전에 실행을 끝나는 줄 끝의 문제. 시도해보십시오.

println!("{:?}", string); 

코드의 세 번째 줄에 넣으십시오. 입력 1 2 3 위해 그것은 (Windows에서) 인쇄됩니다 :

"1 2 3\r\n" 

그래서 어떤 시점에서 당신은 분명 실패 정수로 "3\r\n"을 분석하려고합니다. 문자열에서 후행 및 선행 공백을 제거하는 쉬운 방법은 trim()을 사용하는 것입니다. 이 작품 :

let int_vec: Vec<_> = string.trim().split(" ") 
    .map(|x| x.parse::<u32>().expect("Not an integer!")) 
    .collect(); 
10

Dogberts의 대답에 추가 ... 당신이 미래에 대한 반복자 자신과 문제의이 종류를 디버깅 할 수있을 수있는 방법을 참조하는 것이 도움이 될 수 있습니다.

특성은 inspect 각 항목을 검사하는 데 사용할 수있는 기능을 제공합니다.

let int_vec: Vec<u32> = string.split(" ") 
.inspect(|x| println!("About to parse: {:?}", x)) 
.map(|x| { 
    x.parse::<u32>() 
     .expect("Not an integer!") 
}) 
.inspect(|x| println!("Parsed {:?} successfully!", x)) 
.collect(); 

출력 : 자사는 수의 3

에 도달 할 때 구문 분석을 시도하는 것을

1 2 3 
About to parse: "1" 
Parsed 1 successfully! 
About to parse: "2" 
Parsed 2 successfully! 
About to parse: "3\n" 

thread '<main>' panicked at 'Not an integer!... 

공지 전에 각지도 결과 후 모두 inspect를 사용하도록 코드를 변환 물론, string을 모두 조사 할 수 있습니다. inspect은 반복자가 관련되어있을 때 유용합니다.

+2

TIL :'inspect' 함수가 있습니다! 스트림. –

관련 문제