我写了一个函数来提示输入并返回结果。在这个版本中,返回的字符串包含了用户的一个尾随换行符。我想返回的输入中去掉了那个换行符(而且只是那个换行符):
fn read_with_prompt(prompt: &str) -> io::Result<String> {
let stdout = io::stdout();
let reader = io::stdin();
let mut input = String::new();
print!("{}", prompt);
stdout.lock().flush().unwrap();
reader.read_line(&mut input)?;
// TODO: Remove trailing newline if present
Ok(input)
}
仅删除单个尾随换行符的原因是,此函数还将用于提示输入密码(适当使用termios以停止回显),如果某人的密码有尾随空格,则应保留。
在对如何删除字符串末尾的换行符进行了大量的讨论之后,我最终使用了trim_right_matches
,但是它返回了一个&str
,我尝试使用Cow
来处理这个问题,但是错误仍然指出input
变量的生存时间不够长。
fn read_with_prompt<'a>(prompt: &str) -> io::Result<Cow<'a, str>> {
let stdout = io::stdout();
let reader = io::stdin();
let mut input = String::new();
print!("{}", prompt);
stdout.lock().flush().unwrap();
reader.read_line(&mut input)?;
let mut trimmed = false;
Ok(Cow::Borrowed(input.trim_right_matches(|c| {
if !trimmed && c == '\n' {
trimmed = true;
true
}
else {
false
}
})))
}
错误:
error[E0515]: cannot return value referencing local variable `input`
--> src/lib.rs:13:5
|
13 | Ok(Cow::Borrowed(input.trim_right_matches(|c| {
| ^ ----- `input` is borrowed here
| _____|
| |
14 | | if !trimmed && c == '\n' {
15 | | trimmed = true;
16 | | true
... |
20 | | }
21 | | })))
| |________^ returns a value referencing data owned by the current function
基于previous questions along these lines,这似乎是不可能的。这是分配一个新字符串的唯一选择吗?似乎应该有一种方法来修剪字符串而不复制它(在C中,你只需用'\0'
替换'\n'
)。
6条答案
按热度按时间f87krz0w1#
您可以使用
String::pop
或String::truncate
:uujelgoq2#
一种跨平台的方法是在不重新分配字符串的情况下剥离单个尾随换行符:
这将从字符串末尾去掉
"\n"
或"\r\n"
,但不去掉其他空格。eivnm1vs3#
带有
strip_suffix
这将删除一个尾随的
\r\n
或\n
:如果有多个换行符,则只删除最后一个。
如果字符串末尾没有换行符,则字符串保持不变。
一些测试:
2jcobegt4#
比已接受的解决方案更通用的解决方案,适用于任何类型的行尾:
2lpgd9685#
编辑:我刚刚意识到OP正在寻找 * 而不是 * 复制字符串......所以只需要注意这实际上复制了字符串。
我是一个Rust新手,所以我不知道这个函数是什么时候引入的,但是考虑使用
String::lines
方法。看起来它应该以一种可靠的方式跨平台工作,并且在我的本地开发中,表现得像OP所寻找的那样。参考:https://doc.rust-lang.org/stable/std/string/struct.String.html#method.lines
o4hqfura6#
如果您已经拥有了一个
String
,那么您不需要仅仅为了去除尾随的新行而进行新的分配。下面是一个跨平台示例,它删除了多个尾随的
\r\n
或\n
:现在,让我们测试一下(操场链接:https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=ec2f6f60bdde32ccfeb8fa0c63a06f54):