String 从字符串中删除单个尾随换行符而不进行克隆
我编写了一个函数来提示输入并返回结果。在这个版本中,返回的字符串包含一个来自用户的尾随换行符。我想返回删除了该换行符(以及该换行符)的输入:String 从字符串中删除单个尾随换行符而不进行克隆,string,rust,String,Rust,我编写了一个函数来提示输入并返回结果。在这个版本中,返回的字符串包含一个来自用户的尾随换行符。我想返回删除了该换行符(以及该换行符)的输入: fn使用提示读取提示(提示:&str)->io::Result{ 设stdout=io::stdout(); 让reader=io::stdin(); 让mut input=String::new(); 打印!(“{}”,提示); stdout.lock().flush().unwrap(); 读卡器。读卡器行(&mut输入)?; //TODO:删除尾部换
fn使用提示读取提示(提示:&str)->io::Result{
设stdout=io::stdout();
让reader=io::stdin();
让mut input=String::new();
打印!(“{}”,提示);
stdout.lock().flush().unwrap();
读卡器。读卡器行(&mut输入)?;
//TODO:删除尾部换行符(如果存在)
Ok(输入)
}
仅删除单个尾随换行符的原因是,此函数还将用于提示输入密码(适当使用以停止回显),如果某人的密码有尾随空格,则应保留此选项
在对如何实际删除字符串末尾的一个换行符大惊小怪之后,我最终使用了trim\u right\u matches
。但是,它返回一个&str
。我尝试使用Cow
来处理这个问题,但是错误仍然表明input
变量的寿命不够长
fn在提示下读取\u>{
设stdout=io::stdout();
让reader=io::stdin();
让mut input=String::new();
打印!(“{}”,提示);
stdout.lock().flush().unwrap();
读卡器。读卡器行(&mut输入)?;
让mut-trimmed=false;
Ok(Cow::借用(输入。修剪右)匹配(| c |{
如果!trimmed&&c=='\n'{
修剪=真;
真的
}
否则{
假的
}
})))
}
错误:
错误[E0515]:无法返回引用局部变量'input'的值`
-->src/lib.rs:13:5
|
13 |正常(Cow::借用(输入。修剪|右|匹配(| c |{
|^-----“input”在这里借用
| _____|
| |
14 | |如果!修剪&&c=='\n'{
15 | |修剪=真;
16 | |正确
... |
20 | | }
21 | | })))
|| ____ ^返回一个值,该值引用当前函数拥有的数据
基于这一点,这似乎是不可能的。是否只有一个选项可以分配删除了尾随换行符的新字符串?似乎应该有一种方法可以在不复制字符串的情况下修剪字符串(在C中,您只需将'\n'
替换为'\0'
)。您可以使用或:
您可以使用或:
比公认的解决方案更通用的解决方案,适用于任何类型的行尾:
fn main(){
让mut s=“hello\r\n”。to_string();
设len_withoutclf=s.trim_right().len();
s、 截断(len_,不带LUTLF);
assert_eq!(“hello”、&s);
}
一种比公认的更通用的解决方案,适用于任何类型的行尾:
fn main(){
让mut s=“hello\r\n”。to_string();
设len_withoutclf=s.trim_right().len();
s、 截断(len_,不带LUTLF);
assert_eq!(“hello”、&s);
}
在不重新分配字符串的情况下剥离单个尾随新行的跨平台方法如下:
fn trim_newline(s: &mut String) {
if s.ends_with('\n') {
s.pop();
if s.ends_with('\r') {
s.pop();
}
}
}
这将从字符串的末尾删除
“\n”
或“\r\n”
,但不包含额外的空格。一种跨平台的方法,可以在不重新分配字符串的情况下删除单个尾随换行符:
fn trim_newline(s: &mut String) {
if s.ends_with('\n') {
s.pop();
if s.ends_with('\r') {
s.pop();
}
}
}
这将从字符串末尾删除
“\n”
或“\r\n”
,但不会增加空格。编辑:我刚刚意识到OP希望不复制字符串。。。请注意,这实际上复制了字符串:(
我是一个生锈新手,所以我不知道这个函数是什么时候被引入的,但是考虑使用<代码> String::Letry方法。看起来它应该以可靠的方式跨平台运行,并且在我的本地开发中,看起来像OP正在寻找的那样。
使用std::io::stdin;
fn main(){
println!(“输入一行文本:”);
让mut buf=String::new();
stdin().read_行(&mut buf).expect(“读取输入失败”);
让我的_str=buf.lines()
.next().expect(“无法读取条目”);
println!(“您输入:[{}]”,my_str);
}
参考资料:编辑:我刚刚意识到OP希望不复制字符串…所以请注意,这实际上复制了字符串:(
我是一个生锈新手,所以我不知道这个函数是什么时候被引入的,但是考虑使用<代码> String::Letry方法。看起来它应该以可靠的方式跨平台运行,并且在我的本地开发中,看起来像OP正在寻找的那样。
使用std::io::stdin;
fn main(){
println!(“输入一行文本:”);
让mut buf=String::new();
stdin().read_行(&mut buf).expect(“读取输入失败”);
让我的_str=buf.lines()
.next().expect(“无法读取条目”);
println!(“您输入:[{}]”,my_str);
}
参考资料:
这将删除一个尾随的\r\n
或\n
:
fn strip_trailing_newline(input: &str) -> &str {
return input.strip_suffix("\r\n")
.or(input.strip_suffix("\n"))
.unwrap_or(&input);
}
一些测试:
#[test]
fn strip_newline_works(){
assert_eq!(strip_trailing_newline("Test0\r\n\r\n"), "Test0\r\n");
assert_eq!(strip_trailing_newline("Test1\r\n"), "Test1");
assert_eq!(strip_trailing_newline("Test2\n"), "Test2");
assert_eq!(strip_trailing_newline("Test3"), "Test3");
}
具有
这将删除一个尾随的\r\n
或\n
:
fn strip_trailing_newline(input: &str) -> &str {
return input.strip_suffix("\r\n")
.or(input.strip_suffix("\n"))
.unwrap_or(&input);
}
一些测试:
#[test]
fn strip_newline_works(){
assert_eq!(strip_trailing_newline("Test0\r\n\r\n"), "Test0\r\n");
assert_eq!(strip_trailing_newline("Test1\r\n"), "Test1");
assert_eq!(strip_trailing_newline("Test2\n"), "Test2");
assert_eq!(strip_trailing_newline("Test3"), "Test3");
}
“如果某人的密码有尾随空格,则应保留该空格。”但是trim_right()也会修剪空格。True。更好的解决方案是对最后两个字符/字节进行模式匹配,并确定截断索引。但这不会删除多个换行符。要求不够明确,无法确定这一点。“如果某人的密码有尾随空格,则应保留该空格。”但是trim_right()也会修剪空格。是的。更好的解决方案是在最后两个字符/字节上进行模式匹配,并确定截断索引。但这不会删除多个换行符。要求不够明确,无法决定。我们必须这样做,而不是将其烘焙到语言中,这有点烦人。但我想这确实允许对于操作系统优化?我是个新手