Ich möchte ein Beispiel hinzufügen:
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
int main(int argc, char const *argv[])
{
char buf[20];
fcntl(0, F_SETFL, fcntl(0, F_GETFL) | O_NONBLOCK);
sleep(4);
int numRead = read(0, buf, 4);
if (numRead > 0) {
printf("You said: %s", buf);
}
}
Wenn Sie dieses Programm ausführen, haben Sie 4 Sekunden Zeit, um Standardeingaben bereitzustellen. Wenn keine Eingaben gefunden werden, wird es nicht blockiert und einfach zurückgegeben.
2 Beispielausführungen:
Korays-MacBook-Pro:~ koraytugay$ ./a.out
fda
You said: fda
Korays-MacBook-Pro:~ koraytugay$ ./a.out
Korays-MacBook-Pro:~ koraytugay$
Wie Pete Kirkham fand ich cc.byexamples.com, und es funktionierte für mich. Dort finden Sie eine gute Erklärung des Problems sowie die ncurses-Version.
Mein Code musste einen Anfangsbefehl von der Standardeingabe oder einer Datei übernehmen und dann auf einen Abbruchbefehl warten, während der Anfangsbefehl verarbeitet wurde. Mein Code ist C++, aber Sie sollten scanf()
verwenden können und der Rest, wo ich die C++-Eingabefunktion getline()
verwende .
Das Fleisch ist eine Funktion, die prüft, ob Eingaben verfügbar sind:
#include <unistd.h>
#include <stdio.h>
#include <sys/select.h>
// cc.byexamples.com calls this int kbhit(), to mirror the Windows console
// function of the same name. Otherwise, the code is the same.
bool inputAvailable()
{
struct timeval tv;
fd_set fds;
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds);
select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
return (FD_ISSET(0, &fds));
}
Dies muss vor jeder stdin-Eingabefunktion aufgerufen werden, wenn ich std::cin
verwendet habe Vor der Verwendung dieser Funktion wurde nie wieder wahr zurückgegeben. Beispiel:main()
hat eine Schleife, die so aussieht:
int main(int argc, char* argv[])
{
std::string initialCommand;
if (argc > 1) {
// Code to get the initial command from a file
} else {
while (!inputAvailable()) {
std::cout << "Waiting for input (Ctrl-C to cancel)..." << std::endl;
sleep(1);
}
std::getline(std::cin, initialCommand);
}
// Start a thread class instance 'jobThread' to run the command
// Start a thread class instance 'inputThread' to look for further commands
return 0;
}
Im Eingabe-Thread wurden neue Befehle zu einer Warteschlange hinzugefügt, die periodisch von jobThread
verarbeitet wurde . Die inputThread
sah ungefähr so aus:
THREAD_RETURN inputThread()
{
while( !cancelled() ) {
if (inputAvailable()) {
std::string nextCommand;
getline(std::cin, nextCommand);
commandQueue.lock();
commandQueue.add(nextCommand);
commandQueue.unlock();
} else {
sleep(1);
}
}
return 0;
}
Diese Funktion könnte wahrscheinlich in main()
gewesen sein , aber ich arbeite mit einer bestehenden Codebasis, nicht dagegen.
Für mein System war keine Eingabe verfügbar, bis ein Zeilenumbruch gesendet wurde, was genau das war, was ich wollte. Wenn Sie jedes Zeichen bei der Eingabe lesen möchten, müssen Sie den "kanonischen Modus" auf stdin deaktivieren. cc.byexamples.com hat einige Vorschläge, die ich nicht ausprobiert habe, aber der Rest hat funktioniert, also sollte es funktionieren.