我是一个新手rust程序员,我正在编写一个程序,打印一个表,并使用循环从用户那里获取数值,每次用户输入数值时,表都会更新并再次打印,直到收到所有值.

            class1      class2      class3      class4      class5
Sensor      0           0           0           0           0
visual      0           0           0           0           0

我想将光标放在所需的单元格上(如果可能,闪烁),用户将为其输入值.这意味着在第一次迭代时,光标应位于单元格sensor-class1处,第二次迭代应位于单元格sensor-class2处,以此类推.

我搜索了一会儿,似乎termion是解决方案,但print!("{}", termion::cursor::Goto((10 * i).try_into().unwrap(), j));

extern crate termion;
use std::io;

fn main() {
    let mut sensor_data = [0; 5];
    let mut visual_data = [0; 5];

    for j in 1..3 {
        for i in 1..6 {
            print!("{}", termion::clear::All);
            print!("{}", termion::cursor::Goto(1, 1));

            println!(
                "{0: <10}  {1: <10}  {2: <10}  {3: <10}  {4: <10}  {5: <10}",
                "", "class1", "class2", "class3", "class4", "class5"
            );
            println!(
                "{0: <10}  {1: <10}  {2: <10}  {3: <10}  {4: <10}  {5: <10}",
                "Sensor",
                sensor_data[0],
                sensor_data[1],
                sensor_data[2],
                sensor_data[3],
                sensor_data[4]
            );
            println!(
                "{0: <10}  {1: <10}  {2: <10}  {3: <10}  {4: <10}  {5: <10}",
                "visual",
                visual_data[0],
                visual_data[1],
                visual_data[2],
                visual_data[3],
                visual_data[4]
            );

            //update the cursor position for user input

            let mut input = String::new();
            io::stdin()
                .read_line(&mut input)
                .expect("Failed to read line");
            if j == 1 {sensor_data[i - 1] = input.trim().parse().expect("Please type a number!");}
            else {visual_data[i - 1] = input.trim().parse().expect("Please type a number!");}
        }
    }
// print the complete table and go on
}


推荐答案

我认为主要是你缺了stdout().flush()分.

print!()println!()相反,not写的是换行符.在大多数系统上,换行符会导致刷新,但由于没有换行符,Goto会卡在写入缓冲区中.

一个简单的修复方法是手动设置为flush(),如下面的代码示例所示.

不过,更合适的方法是在raw模式下访问终端,首先禁用缓冲区.

use std::io::{self, Write};

fn main() {
    let mut sensor_data = [0; 5];
    let mut visual_data = [0; 5];

    for j in 1..3 {
        for i in 1..6 {
            print!("{}", termion::clear::All);
            print!("{}", termion::cursor::Goto(1, 1));

            println!(
                "{0: <10}  {1: <10}  {2: <10}  {3: <10}  {4: <10}  {5: <10}",
                "", "class1", "class2", "class3", "class4", "class5"
            );
            println!(
                "{0: <10}  {1: <10}  {2: <10}  {3: <10}  {4: <10}  {5: <10}",
                "Sensor",
                sensor_data[0],
                sensor_data[1],
                sensor_data[2],
                sensor_data[3],
                sensor_data[4]
            );
            println!(
                "{0: <10}  {1: <10}  {2: <10}  {3: <10}  {4: <10}  {5: <10}",
                "visual",
                visual_data[0],
                visual_data[1],
                visual_data[2],
                visual_data[3],
                visual_data[4]
            );

            //update the cursor position for user input
            print!("{}", termion::cursor::Goto(12 * i + 1, j + 1));
            io::stdout().flush().unwrap();

            let mut input = String::new();
            io::stdin()
                .read_line(&mut input)
                .expect("Failed to read line");
            if j == 1 {
                sensor_data[i as usize - 1] = input.trim().parse().expect("Please type a number!");
            } else {
                visual_data[i as usize - 1] = input.trim().parse().expect("Please type a number!");
            }
        }
    }
    // print the complete table and go on
}

我添加的其他次要修复:

  • 移除extern crate,因为不再需要或建议
  • 将类型i更改为u16,并将其转换为usize,而不是相反,以避免unwrap()

Rust相关问答推荐

在‘await’点上使用‘std::同步::Mutex’是否总是会导致僵局?

通用池类型xsx

程序退出后只写入指定管道的数据

在HashMap中插入Vacant条目的可变借位问题

在特征中使用Async时,如何解决不透明类型`impl Future<;out=self>;`不满足其关联的类型边界和警告?

如何获取Serde struct 的默认实例

为什么这是&q;,而让&q;循环是无限循环?

带参考文献的 rust 元组解构

在运行特定测试时,如何 suppress cargo test 的空输出?

为什么在 Allocator API 中 allocate() 使用 `[u8]` 而 deallocate 使用 `u8` ?

提取指向特征函数的原始指针

Rust 重写函数参数

将引用移动到线程中

我可以禁用发布模式的开发依赖功能吗?

如何基于常量在Rust中跳过一个测试

Rust与_有何区别?

不安全块不返回预期值

为什么 no_std crate 可以依赖于使用 std 的 crate?

如何在没有 `make_contiguous()` 的情况下对 VecDeque 进行排序或反转?

传递 Option<&mut T> 时何时需要 mut