PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Kommt die Eingabe über den "<"-Operator?



KL47
21-11-2004, 00:05
Hallo,

ich würde gerne überprüfen, ob per "<" (oder "|", tee, etc.) ein Eingabestream an das Programm übergeben wurde. Wenn ja, soll er den Stream auslesen, ansonsten was anderes tun.

Ich habe also z.B. das Programm "mytest". Wird jetzt "mytest" eingegeben soll der Hilfe-Bildschirm erscheinen. Wird aber "mytest < textdatei.txt" eingegeben, soll das Programm den Stream auslesen und z.B. die Textdatei zeilenweise ausgeben.

"if (!cin.eof())" ist bei mir immer true, egal ob ich nen Stream ans Programm weiterleite ("mytest < textdatei.txt") oder nicht. Wenn ich dann mit cin.get() ein Zeichen auslese, liest er zwar korrekt ein Zeichen aus der Textdatei wenn ich die weiterleite aber wenn ich die nicht weiterleite nimmt er stattdessen die Tastatureingabe, der Benutzer muss also was eingeben, und das ist nicht Sinn der Sache.

Jemand ne Idee? Danke. :)

Deever
21-11-2004, 07:57
und das ist nicht Sinn der Sache.
Doch, genau das ist der Sinn dahinter. Kommandos sollen von stdin lesen (und die Shell hat dafür zu sorgen, daß der richtige Filedeskriptor auf stdin "gemappt" ist). Allenfalls kannst du ja einen Parameter ``-f filename'' implementiern.

HTH!
/dev

anda_skoa
21-11-2004, 08:37
Du brauchst einen Kommandozeilenparameter, der dem Programm sagt, dass er Stdin benutzen soll.
Ähnlich wie da zB tar macht.

Ciao,
_

KL47
21-11-2004, 13:04
Eigentlich wollte ich das so wie mit "less" machen. Wenn man "less" eingibt kommt "missing filename", er erwartet aber keine Eingabe vom Benutzer. Wenn man aber "less < textdatei.txt" macht, gibt er die Textdatei aus. Irgendwoher muss less ja dann wissen, dass stdin nicht leer ist...

Pingu
21-11-2004, 13:23
Ich bin jetzt nicht mehr ganz so firm in C++. Aber ich habe mich gerade mal umgesehen und die Methode istream::readsome() (http://www.cplusplus.com/ref/iostream/istream/readsome.html) gefunden. Vielleicht wäre die ein Ansatz.

Pingu

KL47
21-11-2004, 14:17
Danke Pingu, ganz genau das wars zwar nicht aber auf der Seite hab ich dann was hilfreiches gefunden :)



#include <iostream>
#include <fstream>

int main ()
{
std::cin.seekg (0, std::ios::end);
int length = std::cin.tellg();

if (length == -1)
{
std::cerr << "No file passed!" << std::endl;
return -1;
}
else
{
return 0;
}
}


Funktioniert auch wenn man ne leere Datei (z.B. /dev/null) übergibt, die hat dann eben die Länge "0", wenn garkeine Datei übergeben wird ist die Länge "-1".

panzi
21-11-2004, 15:18
Ich hätt ne andere Lösung, aber da hätt ich net in jedem fall die Garantie das es kompilierbar ist, nur wenn du unter nen POSIX kompatieblen System arbeitest (kA ob das Windows auch kann), und das ist C, nicht C++:
Mit isatty() (http://unixhelp.ed.ac.uk/CGI/man-cgi?isatty) kannst du rausbekommen ob ein filedescriptor von einer Datei oder einen Terminal ließt. Um den Filedescriptor zu einer FILE (also z.B. stdin) zu bekommen verwendes't du fileno() (http://unixhelp.ed.ac.uk/CGI/man-cgi?fileno).
Also:
if( isatty( fileno( stdin ) ) ) {
puts( "Ich leße von nem Terminal!" );
}

Ich bin ja generell gegen das mischen von C und C++, aber isatty() gibts halt einfach unter C++ net. Und das ist netmal ANSI C, aber ich denk POSIX oder ein anderer quasi Unix Standard (BSD, X/OPEN).

panzi
21-11-2004, 20:40
Achja, mit fstat() (http://unixhelp.ed.ac.uk/CGI/man-cgi?fstat) kann man das eigentlich noch genauer feststellen. Nur braucht man da wieder einen Filedescriptor:
struct stat buf;
int ret = fstat( fileno( stdin ), &buf );