Ich möchte im Grunde zu testen, ob stdin Eingabe hat (wie wenn Sie echo und Rohr es). Ich habe Lösungen gefunden, die funktionieren, aber sie sind hässlich, und ich mag meine Lösungen sauber zu sein.
Unter Linux verwende ich dies:
bool StdinOpen() {
FILE* handle = popen("test -p /dev/stdin", "r");
return pclose(handle) == 0;
}
Ich weiß, dass ich mehr Fehlerbehandlung hinzufügen sollte, aber das ist nicht der Punkt.
Unter Windows verwende ich dies:
bool StdinOpen() {
static HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
DWORD bytes_left;
PeekNamedPipe(handle, NULL, 0, NULL, &bytes_left, NULL);
return bytes_left;
}
Das ist gut für Linux, aber ich möchte wissen, was sind die gleichwertigen APIs, die ich ohne Verwendung einer Pipe aufrufen kann (wie für test -f $file
Sie tun fopen($file, "r") != NULL
). Ich habe die Vermutung, dass ich open("/dev/stdin", "r")
und dasselbe tun, aber ich möchte wissen, wie ich es am besten anstellen soll.
Zusammenfassung: Ich möchte wissen, welche APIs ich verwenden könnte, um test -p /dev/stdin
für Linux, und, falls Sie eine bessere Lösung für Windows kennen.
0 Stimmen
Ihr
PeekNamedPipe
Lösung schlägt fehl, wenn die Standardeingabe ein Dateihandle (und nicht eine Pipe) ist. Außerdem ist Ihrhandle
Variable sollte nicht statisch sein. Wenn das Handle umgeleitet wird, während Ihre Anwendung läuft, werden Sie später eine Überraschung erleben.0 Stimmen
@Billy: Ich glaube nicht, dass ein Handle willkürlich umgeleitet werden kann. Sicher, Sie könnten ändern, was Sie als stdin betrachten, aber das alte Handle ist immer noch da. Aber ich stimme mit dem ersten Teil überein.
0 Stimmen
Lionel B stellt einige Codes für Linux zur Verfügung unter bytes.com/topic/c/answers/841283-wie-erstelle-ich-einen-nicht-blockierenden-aufruf-cin - die Diskussion ist auch lesenswert.
0 Stimmen
Ich könnte testen, ob stdin eine Pipe ist, indem ich
DWORD dw; !GetConsoleMode(handle, &dw)
und verwenden Sie die aktuelle Methode, andernfalls verwenden Sie_kbhit() != 0
. Was denken Sie?