使C ++不等待用户输入 [英] Make c++ not wait for user input

查看:206
本文介绍了使C ++不等待用户输入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,我正在尝试使c ++ WinSock2聊天,只是为了学习。
这是一个控制台应用程序,我想接受用户输入(用于发送给对方),但我仍然希望能够接受。 (这样您就可以写一条消息,同时仍然能够接收到一条消息)...



使用 cin>>时,输入; 程序暂停,直到用户输入了某些内容为止,即该程序是基于回合的(一个用户写了东西然后发送,然后另一个用户写了东西然后发送)。 / p>

有没有一种方法可以使用户能够在仍在运行接收内容的同时写东西? (最好是多线程处理以外的方法)

解决方案

如何检查缓冲区是否为空?但是那时代码并不是真正可移植的,因为据我所知,您需要进行一些系统调用。请参见

但也许您可以用一些方法C代码,我将做一些研究并更新我的答案。



UPD:好的,我做到了。您需要的是选择函数。

它可以等待直到 stdin 可供读取为止,这就是我们所需要的。
但是看起来它不适用于C ++流,因此您只需要使用C代码进行读取。



让我们跳转到定义:

int select(int nfds,fd_set * readfds,fd_set * writefds,fd_set * errorfds,struct timeval * timeout)



好,我们只需要检查读缓冲区,所以 writefds errorfds 可能是 NULL 。而且我们只需要检查 stdin ,所以 nfds 1 fds es的数量)



超时呢?它应该是 0 ,所以我们需要初始化变量 struct timeval timeout 并通过<$将秒和纳秒设置为0。 c $ c> timeout.tv_sec = 0 和 timeout.tv_usec = 0



因此,仅剩 readfds 。这也非常简单:我们需要将变量初始化为零,然后添加 stdin

可以使用 fd_set readfds , FD_ZERO(& readfds) FD_SET(STDIN_FILENO,& readfds)



好的,最后一步:函数调用。应该是 select(1,& readfds,NULL,NULL,& timeout)



如果输入缓冲区为空,则返回 0 ,否则为 1



UPD2:看起来它不是C ++流,发生一些奇怪的事情,并且在第一次调用缓冲区为空时中断。我会设法解决问题。



UPD3:好的,现在我知道了。看起来您可以对C ++流使用 select



选择具有非常奇怪的(IMHO)功能:它会重置 readfds 。我不确定如何阻止它执行此操作,因此我只使用了一个 fd_set 变量来保存它,因此您需要添加 fd_set在 readfds 初始化之后,savefds = readfds ,在每次调用后, readfds = savefds 。那是一个糟糕的解决方案,但是我不知道该如何改进。



所以代码是:



初始化:

  fd_set readfds; 
FD_ZERO(& readfds);
FD_SET(STDIN_FILENO,& readfds);
fd_set savefds = readfds;

超时初始化:

  struct timeval超时; 
timeout.tv_sec = 0;
timeout.tv_usec = 0;

和用法:

  if(select(1,& readfds,NULL,NULL,& timeout)){
cin>输入
send(input);
}
readfds = savefds;

UPD4:不要忘记包含 unistd.h cstdlib


So, i am trying to make a c++ WinSock2 chatter, just for learning. It is a console application and i want to take user input (for sending to the counterpart), but i still want to be able to recive. (so you can write a message while still being able to recive one)...

When using cin >> input; the program "pauses" until the user has enterd something, that way it is "turn based" (one user writes something and sends it, then the other user writes something and sends it).

Is there a way to make the user be able to write something WHILE the recive stuff is still running? (Preferably something else than multi threading)

解决方案

What about checking if buffer isn't empty? But code wouldn't be really portable then, because you need to make some system calls as I know. See this.
But maybe you can do it with some C code, I'll do some research and update my answer.

UPD: Ok, I did it. What you need is select function.
It could wait till stdin is ready for read, and that's what we need. But looks like it don't work with C++ streams, so you need to use only C code for reading.

Let's jump to definition:
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout)

Ok, we need to check only read buffer, so writefds and errorfds could be NULL. And we need to check only stdin, so nfds is 1 (number of fdses)

What about timeout? It's should be 0, so we need to initialize variable struct timeval timeout and set seconds and nanoseconds to 0 by timeout.tv_sec = 0 and timeout.tv_usec = 0.

So, only readfds left. It's pretty simple too: we need to initialize variable, "zero" it, and add stdin.
It can be done with fd_set readfds, FD_ZERO(&readfds) and FD_SET(STDIN_FILENO, &readfds).

Okay, final step: function call. It should be select(1, &readfds, NULL, NULL, &timeout).

This would return 0 if input buffer is empty and 1 if it's not.

UPD2: Looks like it's not C++ streams, something strange happens and it breaks when buffer is empty at very first call. I'll try to catch the problem.

UPD3: Ok, Now I figured it out. Looks like you can use select with C++ streams.

Select has VERY strange (IMHO) feature: it resets readfds. I'm not sure how to prevent It from doing this, so I just used one more fd_set variable to hold it, so you need to add fd_set savefds = readfds after readfds initialization, and readfds = savefds after each call. That's awful solution, but I don't know how could I improve it.

So code is:

Initialization:

fd_set readfds;
FD_ZERO(&readfds);
FD_SET(STDIN_FILENO, &readfds);
fd_set savefds = readfds;  

Timeout initialization:

struct timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 0;

And usage:

if (select(1, &readfds, NULL, NULL, &timeout)) {
  cin >> input;
  send(input);
}
readfds = savefds;

UPD4: Don't forget to include unistd.h and cstdlib

这篇关于使C ++不等待用户输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆