将字符串放入控制台时删除并替换文本 $stdin ruby

remove and replace the text when putting a string into the console $stdin ruby

我有一个程序是客户端,它通过 socket.

与服务器通信

当用户输入一条消息时,如果有另一条消息进来,它会在视觉上打断文本,让用户难以理解。

场景可以这样想

c=0
p=Thread.new do
    loop {
        # this is the messages coming in
        c+=1
        puts c
        sleep 1
    }
end
g=Thread.new do
    loop {
      #this is the user input
      puts $stdin.gets  
    }
end
p.join
g.join

在一些非常慢的打字机的情况下,输出看起来类似于此

1
h2
el3
l4
o5

hello

6

有什么方法可以删除和替换将字符串放入控制台时的文本吗?

edit

所以,现在如果我可以将每个字符分开,我可以将它添加到一个字符串中,并且在线程 p 中放置时,它会放置 "\r" + c 然后打印字符串.

这将允许用户仍然看到他们正在输入的内容,并且不会中断 p 线程。

我不知道如何单独获取每个字符。

这也带来了 "how would backspace work?" 和 "would i need a switch statement for special characters like return and ctrl+c?"

的问题

你的程序是多线程的,你的两个线程都在争夺同一个资源:终端!处理此问题的经典方法是使用 mutex.

保护共享资源

这个想法很简单:每当线程与共享资源(终端)交互时,就将该访问与共享互斥锁同步。这样他们就不会互相践踏。

但是你的情况很棘手,当线程 p 想要使用终端时很容易看到,但在线程 g 中并不容易,因为那只是用户输入。您可能需要做的是在紧密循环中使用 IO#read_nonblock 来逐个字符地获取用户的输入。然后,您可以使用它来检测用户何时暂停输入并花时间解锁互斥锁,从而允许其他线程转储其输出。

请注意,这也会使线程 p 更加复杂,因为它需要能够在等待终端可用时缓冲其输出。

如果您尝试在终端中实现聊天应用程序,"appropriate" 工具是 curses。 curses 库本质上允许您在终端中编写 GUI。它可以让您定义可以单独更新的屏幕的单独区域,还可以让您读取输入而不将其回显到终端。