我写了一个函数来提示输入并返回结果.在此版本中,返回的字符串包含用户的尾随换行符.我想将该换行符(以及该换行符)删除后返回输入:
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)
}
Run Code Online (Sandbox Code Playgroud)
仅删除单个尾随换行符的原因是此函数还将用于提示输入密码(适当使用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
}
})))
}
Run Code Online (Sandbox Code Playgroud)
错误:
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
Run Code Online (Sandbox Code Playgroud)
基于以前的这些问题,似乎这是不可能的.是唯一一个分配删除了尾部换行符的新字符串的选项吗?这似乎应该有修剪不复制它的字符串的方式(在C你只需更换'\n'
用'\0'
).
mal*_*rbo 17
你可以使用String::pop
或String::truncate
:
fn main() {
let mut s = "hello\n".to_string();
s.pop();
assert_eq!("hello", &s);
let mut s = "hello\n".to_string();
let len = s.len();
s.truncate(len - 1);
assert_eq!("hello", &s);
}
Run Code Online (Sandbox Code Playgroud)
比通用解决方案更通用的解决方案,适用于任何类型的行结束:
fn main() {
let mut s = "hello\r\n".to_string();
let len_withoutcrlf = s.trim_right().len();
s.truncate(len_withoutcrlf);
assert_eq!("hello", &s);
}
Run Code Online (Sandbox Code Playgroud)
删除单个尾随换行符而不重新分配字符串的跨平台方法是:
fn trim_newline(s: &mut String) {
if s.ends_with('\n') {
s.pop();
if s.ends_with('\r') {
s.pop();
}
}
}
Run Code Online (Sandbox Code Playgroud)
这将删除字符串中的任意一个"\n"
或"\r\n"
从字符串的末尾删除,但不附加空格。
strip_suffix
这将删除一个尾随\r\n
或\n
:
fn strip_trailing_newline(input: &str) -> &str {
input
.strip_suffix("\r\n")
.or(input.strip_suffix("\n"))
.unwrap_or(input)
}
Run Code Online (Sandbox Code Playgroud)
一些测试:
#[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");
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
10714 次 |
最近记录: |