获取用户输入
在Rust中,获取用户输入并转换成整数通常涉及以下步骤:
下面是一个完整的示例,演示如何实现这个过程:
use std::io;
fn main() {
let number:i32 = get_number_from_input("请输入一个整数:");
println!("你输入的整数是:{}", number);
}
fn get_input_int32(tips:&str)->Option<i32>{
println!("{}", tips);
let mut input = String::new();
io::stdin().read_line(&mut input).expect("读取失败");
input.trim().parse().ok()
}
fn get_number_from_input(tips: &str) -> i32 {
get_input_int32(tips).unwrap_or_else(|| {
println!("输入的不是整数");
std::process::exit(1);
})
}
在这段代码中:
main函数
fn main() {
let number:i32 = get_number_from_input("请输入一个整数:");
println!("你输入的整数是:{}", number);
}
-
main
函数是每个可执行Rust程序的入口点。 - 它调用
get_number_from_input
函数,并传递一个提示字符串"请输入一个整数:
"。 -
get_number_from_input
函数会处理所有的输入逻辑,如果用户输入了一个有效的整数,它会返回这个整数。 -
main
函数将接收到的整数存储在变量number
中,并打印出来。
get_input_int32 函数
fn get_input_int32(tips:&str)->Option<i32>{
println!("{}", tips);
let mut input = String::new();
io::stdin().read_line(&mut input).expect("读取失败");
input.trim().parse().ok()
}
- 这个函数的目的是从用户那里获取一行文本输入,并尝试将其解析为一个整数。
- 它接受一个提示字符串
tips
作为参数,并打印出来,提示用户输入。 - 使用
io::stdin().read_line(&mut input)
从标准输入读取一行文本。&mut input
表示input
是一个可变引用,read_line
会把用户输入的内容写入到input
字符串中。 -
expect("读取失败")
用于处理read_line
可能出现的错误。如果读取失败(例如,输入输出流被关闭),程序会打印"读取失败
"并退出。 -
input.trim()
去除输入字符串前后的空白字符(如空格、制表符、换行符等)。 -
parse()
方法尝试将处理过的字符串转换为i32
类型的整数。这个方法返回一个Result<i32, ParseIntError>
类型的值,其中Ok(i32)
表示解析成功,Err(ParseIntError)
表示解析失败。 -
ok()
方法将Result
转换为Option<i32>
,如果解析成功,返回Some(i32)
,如果解析失败,返回None
。
get_number_from_input 函数
fn get_number_from_input(tips: &str) -> i32 {
get_input_int32(tips).unwrap_or_else(|| {
println!("输入的不是整数");
std::process::exit(1);
})
}
- 这个函数调用
get_input_int32
函数来获取用户输入,并尝试将其解析为整数。 - 如果
get_input_int32
返回Some(i32)
,表示用户输入了一个有效的整数,函数会直接返回这个整数。 - 如果
get_input_int32
返回None
,表示用户输入了无效的内容,函数会执行unwrap_or_else
中的闭包。闭包的概念以后再讲解,现在只要知道有这么个东西。 - 闭包中打印了一条消息"
输入的不是整数
",并调用std::process::exit(1)
来退出程序。std::process::exit(1)
是一个函数,用于以给定的退出状态码退出程序。在这里,退出状态码1
通常表示程序因为错误而退出。
整体上,这段代码展示了如何在Rust中处理用户输入,以及如何将输入转换为特定的数据类型。它也展示了Rust的错误处理机制,包括Result
和Option
类型的使用。希望这个解释能帮助你更好地理解这段代码。
字符串转整数小数
获取了用户输入后,我们经常需要将输入转换为整数或者小数
fn main() {
let my_string = "15";
let number = my_string.parse::<i32>().ok().unwrap_or_else(|| {
println!("输入的不是整数");
std::process::exit(1);
});
println!("number is {}", number);
let my_string = "3.2";
let number = my_string.parse::<f32>().ok().unwrap_or_else(|| {
println!("输入的不是小数");
std::process::exit(1);
});
println!("number is {}", number);
}
字符串操作-切片
获取了用户输入之后,我们经常会对输入的字符串进行各种处理
下面是一个如何对String
类型进行切片操作的例子:
fn main() {
let my_string = String::from("Hello, world!");
// 获取从索引2开始的5个字符的切片
let slice = &my_string[2..7]; // 索引2到索引6(不包括索引7)
println!("{}", slice); // 输出 "llo, "
}
在这个例子中,&my_string[2..7]
创建了一个从my_string
的索引2开始到索引7结束的字符串切片。注意,这里的slice
类型是&str
,因为它是一个引用到String
的一部分,而不是一个新的String
对象。
如果你尝试在不借用String
的情况下进行切片操作,你会得到一个错误,因为Rust不允许对拥有所有权的类型进行切片操作。你必须通过借用(使用&
)来创建一个切片。
同样,切片操作必须遵守索引的有效性。如果尝试创建超出字符串边界的切片,程序将会在运行时发生panic。因此,在切片操作之前,你应该确保索引是有效的。
字符串操作-切片结合长度
fn main() {
let my_string = String::from("Hello, world!");
let len = my_string.len();
let slice = &my_string[(len - 1)..]; //最后一个字
println!("{}", slice); // 输出 "!"
}
格式化选项
在Rust中,格式化字符串字面量和宏(如format!
、println!
、print!
等)支持一系列的格式化选项,这些选项让你能够精确控制输出字符串的格式。下面是一些常用的格式化选项:
-
填充与对齐:
-
width
: 指定最小宽度。如果值的宽度小于这个值,它将在指定的对齐方式下被填充。 -
.precision()
: 对于浮点数,指定小数点后的位数;对于字符串,指定最大长度。 -
^
: 居中对齐。 -
<
: 左对齐(默认)。 -
>
: 右对齐。 -
=
: 在数字的符号和数字之间填充。 -
0
: 使用0
填充数字。
-
-
数字格式:
-
b
: 二进制。 -
o
: 八进制。 -
x
: 十六进制,小写。 -
X
: 十六进制,大写。 -
p
: 指针。 -
e
: 科学记数法,小写。 -
E
: 科学记数法,大写。 - ``: 非负数字前面添加空格。
-
+
: 正数前添加+
号。
-
-
其他:
-
?
: 用于错误处理,会自动调用Display
或Debug
trait。
下面是一些具体的例子,展示了如何使用这些格式化选项:
-
fn main() {
// 填充与对齐
let s = "hello";
println!("{}{}", "123".to_string().pad_left(5), s); // 使用pad_left手动实现左对齐
println!("{:>10}", s); // 右对齐,宽度为10
println!("{:<10}", s); // 左对齐,宽度为10
println!("{:^10}", s); // 居中对齐,宽度为10
// 数字格式
let x = 42;
println!("Binary: {:b}", x); // 二进制
println!("Hex: {:x}", x); // 十六进制,小写
println!("Hex: {:X}", x); // 十六进制,大写
println!("Octal: {:o}", x); // 八进制
// 浮点数格式
let y = 1.23456;
println!("Precision: {:.2}", y); // 保留两位小数
// 指针格式
let z = &x;
println!("Pointer: {:p}", z); // 指针格式
// 错误处理
let result = Ok("success");
println!("{:?}", result); // 使用Debug trait打印
}
在这个例子中,我们使用了不同的格式化选项来控制字符串和数字的输出格式。例如,我们使用了>
和<
来指定数字的右对齐和左对齐,使用了x
和X
来打印十六进制的数字,使用了.{}
来指定浮点数的精度,以及使用了{:?}
来打印错误处理的结果。这些格式化选项提供了强大的格式化能力,让你能够根据需要定制输出。