-- fopen --
Linux fopen(,"r") fopen(,"r") -
fopen(,"rb")
Windows fopen(,"rb") fopen(,"rt")
fopen(,"r")
Schnittmenge fopen(,"rb") fopen(,"r")
-- popen --
Linux popen(,"r") popen(,"r") popen(,"rb");
Windows popen(,"rb") popen(,"rt")
popen(,"r")
Schnittmenge --leer-- popen(,"r")
Möchte man aus einer Datei binär lesen, dann benutzt man
fopen (name, "rb");
Das Äquivalent bei Lesen aus einer Pipe wäre
popen (name, "rb");
Leider geht das unter Linux nicht. Was soll der Schwachfug?
Wie mache ich portables Programmieren so schwer wie möglich oder
was ist das Ziel, was ich hier nicht M$ anlasten kann und will???
Außerdem ist es eine (wie viele andere auch) unnötige Symmetriebrechung.
Unästhetisch.
--
Frank Klemm
> Leider geht das unter Linux nicht. Was soll der Schwachfug?
Pech, SUSv2 spezifiziert nur "r" und "w".
> Wie mache ich portables Programmieren so schwer wie möglich oder
> was ist das Ziel, was ich hier nicht M$ anlasten kann und will?
Auf den Systemen, die klassischerweise popen() implementieren, hat "b"
keinen Effekt.
> Binäres Lesen Text lesen Fehler "Bad Args"
[Viele Beispiele gelöscht]
> Möchte man aus einer Datei binär lesen, dann benutzt man
> fopen (name, "rb");
> Das Äquivalent bei Lesen aus einer Pipe wäre
> popen (name, "rb");
> Leider geht das unter Linux nicht. Was soll der Schwachfug?
> Wie mache ich portables Programmieren so schwer wie möglich oder
> was ist das Ziel, was ich hier nicht M$ anlasten kann und will???
Da fragst Du am besten MS, was der Schwachfug soll. Unter UNIX gibt es
keine blödsinnige Unterscheidung zwischen Textdateien und binären Dateien.
Die gibt es nur bei Windows. Bei fopen() wird das "b" zwar großzügig
akzeptiert, aber ignoriert. Bei fopen() wurde das Flag wohl akzeptiert, um
dem ISO C standard gerecht zu werden. popen() ist dagegen in ISO C nicht
definiert (sondern POSIX). SUSV2 sagt unter anderen dazu:
The mode argument to popen() is a string that specifies I/O mode:
If mode is r, when the child process is started its file descriptor
STDOUT_FILENO will be the writable end of the pipe, and the file descriptor
fileno(stream) in the calling process, where stream is the stream pointer
returned by popen(), will be the readable end of the pipe.
If mode is w, when the child process is started its file descriptor
STDIN_FILENO will be the readable end of the pipe, and the file descriptor
fileno(stream) in the calling process, where stream is the stream pointer
returned by popen(), will be the writable end of the pipe.
If mode is any other value, the result is undefined.
Also ist die Behandlung von "b" in popen() implementationsabhängig -
man kann es akzeptieren, muß aber nicht. Solaris scheint ein "b" Flag
anscheinend auch bei popen() zu akzeptieren und ignorieren.
> Außerdem ist es eine (wie viele andere auch) unnötige Symmetriebrechung.
> Unästhetisch.
Jaja, Windows ist unästhetisch, da es unbedingt zwischen Textdateien und
Nicht-Textdateien unterscheiden wollte.
Was spricht gegen ein
#ifdef WINDOWS
#define RB "rb"
#define WB "wb"
#else
#define RB "r"
#define WB "w"
#endif
--
Daniel
> Da fragst Du am besten MS, was der Schwachfug soll. Unter UNIX gibt es
> keine blödsinnige Unterscheidung zwischen Textdateien und binären Dateien.
> Die gibt es nur bei Windows.
Auch bei VMS. ;-)
> Was spricht gegen ein
>
> #ifdef WINDOWS
> #define RB "rb"
> #define WB "wb"
> #else
> #define RB "r"
> #define WB "w"
> #endif
Das ist ein klassischer Mißbrauch des C-Präprozessors. Eine Routine,
die popen() kapselt, täte es genauso. Es gibt hier keinen Grund,
Präprozessormakros über die halbe Anwendung zu verstreuen.
Das CRLF-Zeilenende ist keine Eigenschaft des Betriebssystems Windows oder
DOS, sondern es ist eine Übereinkunft einer Großzahl der Programme Textdaten
so abzuspeichern, um den Datenaustausch zu erleichtern.
We das nicht erkennt, hat seinen Kopf nicht benutzt.
Man könnte auf einem NT-Kernel basierend auch 0A als Zeilenende nutzen.
Nur kommen damit viele Programme nicht zurecht (z.B. Notepad), deswegen
versucht sich jeder an die Konvention zu halten.
Und es gibt mittlerweile noch wesentlich mehr Unterschiede in der
Textrepräsenation, ich denke nur an Codepages, Unicode, UTF-8, um bei den
Plainformaten zu bleiben.
Weiterhin könnte man sich auch einfallen lassen, bei Textdateien Metadaten
mit abzuspeichern um so was wie:
fseek ( fp, 1000000, SEEK_LINE );
effizient zu unterstützen (Positioniere auf die Millionste Zeile in der
Datei).
>> Was spricht gegen ein
>>
>> #ifdef WINDOWS
>> #define RB "rb"
>> #define WB "wb"
>> #else
>> #define RB "r"
>> #define WB "w"
>> #endif
>
> Das ist ein klassischer Mißbrauch des C-Präprozessors. Eine Routine,
> die popen() kapselt, täte es genauso. Es gibt hier keinen Grund,
> Präprozessormakros über die halbe Anwendung zu verstreuen.
>
Richtig. Ich habe mittlerweile 60 Kbyte an nur solchem Geraffel zusammen.
Die meisten Unterschiede sind marginal und unnötig.
--
Frank Klemm
Es ist eine Notwendigkeit, daß ein Compiler 'irgendein' definiertes
Datenformat erkennt. Des weiteren ist das aus Portabilitätserwägungen
heraus wünschenswert.
> Das CRLF-Zeilenende ist keine Eigenschaft des Betriebssystems Windows oder
> DOS, sondern
... ein schwachsinniges Relikt aus Schreibmaschinenzeiten, wo
'Wagenrücklauf' und 'Neue Zeile' aus ganz anderen Gründen
unterschiedliche Dinge waren.
> es ist eine Übereinkunft einer Großzahl der Programme Textdaten
> so abzuspeichern, um den Datenaustausch zu erleichtern.
Wie alle schwachsinnigen Relikte wird es uns aus Gründen der
Abwärtskompatibilität erhalten bleiben, obwohl es bereits einen
'Wagenrücklauf-Knopf' auf jeder normalen Tastatur gibt und an eine
Unterstützung für manuelles Arbeiten gar nicht gedacht war.
Aber mutmaßlich hat 'irgendjemand' vor 10.000 Jahren mal einen
Terminaltreiber geschrieben, der ein entsprechendes Steuerzeichen
benutzt hat.
> Man könnte auf einem NT-Kernel basierend auch 0A als Zeilenende nutzen.
> Nur kommen damit viele Programme nicht zurecht (z.B. Notepad),
Das bei M$ jede blödsinnige Idee aus den Siebzigern auch heute noch
fröhliche Urständ feiert, ist nicht überraschend.
> Und es gibt mittlerweile noch wesentlich mehr Unterschiede in der
> Textrepräsenation, ich denke nur an Codepages, Unicode, UTF-8, um bei den
> Plainformaten zu bleiben.
Welcher Teil des Begriffes 'portable character set' ist an Dir
vorbeigerauscht?
> Weiterhin könnte man sich auch einfallen lassen, bei Textdateien Metadaten
> mit abzuspeichern um so was wie:
>
> fseek ( fp, 1000000, SEEK_LINE );
>
> effizient zu unterstützen
Weiterhin könnte man auf Textdateien verzichten, falls man Dinge
vorhat, die sich damit nicht vernünftig machen lassen. Aber Listen in
Listen sind als Datenstruktur ziemlich flexibel, deswegen sollte man
sich das gut überlegen.
Vor allem könnte man den Blödsinn bleiben lassen und einen externen
Indx, zB als .dbm, benutzen, das hätte denselben Effekt und würde ein
gutes Stück Arbeit sparen. Programme sind ziemlich gut da drin, für
Menschen nicht eindeutig zusammenhängende Dinge zu behalten, wozu der
Aufwand?
Von der Win-typischen Konditionierung auf 'core dump als
Datenaustauschformat' (schön einfach zu implementieren) abgesehen?
--
near
distant
Aus diesem Grunde ignoriert man unter Unix das "b".
> Das CRLF-Zeilenende ist keine Eigenschaft des Betriebssystems Windows oder
> DOS, sondern es ist eine Übereinkunft einer Großzahl der Programme Textdaten
> so abzuspeichern, um den Datenaustausch zu erleichtern.
Aha, und warum findet man es dann hauptsaechlich unter Windows und
nicht unter Unix?
> Weiterhin könnte man sich auch einfallen lassen, bei Textdateien Metadaten
> mit abzuspeichern um so was wie:
>
> fseek ( fp, 1000000, SEEK_LINE );
Mit einem Filesystem wie ext2, dass "sparese files' unterstuetzt ja
kein Problem. Sinvoll? Naja.
Gruss,
Florian.
Ich denke, Frank meinte einen echten Index,
d.h. ein fpos_t line[], und "SEEK_LINE" ermittelt
den eigentlichen Offset indirekt über diesen Index.
Deinen Vorschlag verstehe ich aber so:
char file[MAX_LINE_LEN][]
oder in Pascal
type line = array [0..MAX_LINE_LEN] of char;
var f: file of line;
MAX_LINE_LEN ist dabei ein vielfaches der Blockgröße
des Dateisystems, also mindestens 512 Byte.
Leere Zeilen verbrauchen dann ausschließlich Sparse Blocks,
aber jede Zeile mindestens einen Block.
Ich denke, dass sogar Extrem-Bloat-Datenbanken wie Oracle
das effizienter machen.
IMHO wäre es ein brauchbarer Ansatz, jede Zeile in einer
eigenen Datei zu speichern, und das ganze Verzeichnis als
einen Text zu verstehen. Ich denke, dass reiserfs diese
sogar halbwegs effizient löst, immerhin können sich kleine
Dateien dort Blöcke teilen.
AFAIK ist der Kernel aber nicht darauf ausgelegt,
so einfach mal 10000e Dateien offen zu haben,
oder ständig
fd = open(...)
size = lseek(fd, 0, SEEK_END)
read(fd, buf, size)
close(fd)
zu machen.
>> Das CRLF-Zeilenende ist keine Eigenschaft des Betriebssystems Windows oder
>> DOS, sondern es ist eine Übereinkunft einer Großzahl der Programme Textdaten
>> so abzuspeichern, um den Datenaustausch zu erleichtern.
>
> Aha, und warum findet man es dann hauptsaechlich unter Windows und
> nicht unter Unix?
CRLF ist auch unter UNIX sehr weit verbreitet. Nur nicht in
Textdateien.
Er hatte es aber von Textdateien. CRLF kenne ich unter Unix nur in
Uebertragungsprotokollen.
Gruss,
Florian.
Was jetzt? Sparse files? Ja. Metadaten an einer festen Stelle
innerhalb der "Textdatei"? Warum?
Gruss,
Florian.
fopen() ignoriert es.
popen() boykottiert es.
--
Frank Klemm
> fopen() ignoriert es.
> popen() boykottiert es.
popen() war nie dazu gedacht, auf nicht-Unixen zu laufen. Es
gibt keinen vernuenftigen Grund, sich als *neue* Konvention das
implizite Einfuegen (und Lesen) von CR-Zeichen bei Textdateien
auszudenken, wenn man nur ein *bisschen* Wert auf Portabilitaet
legt (bedenke: Unix war zur Zeit des (Nicht-) Designs der MS
Betriebssysteme laengst bekannt). Du suchst den Schuldigen an
der falschen Stelle.
Gruss,
Herbert
--
Ed, the greatest WYGIWYG editor of all.
-=-=- -=-=-=-=-
Dipl.Ing. Martin "Herbert" Dietze -=-=- The University of Buckingham -=-=-
Es war eher in der Nähe von CP/M anzusiedeln. Und hier spielte die
Dateikompatiblität zu CP/M eine Rolle. Das Zeilenende mit CRLF zu markieren
ist auch keine Eigenschaft von CP/M, sondern einen Übereinkunft von
Programmen und Geräten, die unter CP/M verwendet worden.
Gedruckt wurde z.B. mit
C>type Datei.txt^P
Hallo Welt
C>^P
Und warum C neben Binärdateien gerade zweidimensionale char-Felder
mit Inband-Signaling und fehlenden direkten Zugriffsmöglichkeiten
unterstützt, ist mir bis heute noch unklar.
--
Frank Klemm
> Wen hat 1981-82 Unix als Desktop-OS interessiert? Benutze doch mal Deinen
> Kopf!
Mach ich, danke fuer den Tip.
> Es war eher in der Nähe von CP/M anzusiedeln. Und hier spielte die
> Dateikompatiblität zu CP/M eine Rolle. Das Zeilenende mit CRLF zu markieren
> ist auch keine Eigenschaft von CP/M, sondern einen Übereinkunft von
> Programmen und Geräten, die unter CP/M verwendet worden.
Ja und? Aendert das etwas? Meinst Du, dass haette beim Design
des Unix-Aufrufes popen() beruecksichtigt werden muessen?
Gruss,
Herbert
--
Steht ein Bratscher vor 'ner Kneipe.
Falls ich eine Zahlen über die relativen Häufigkeiten hätte, würdest
Du die nicht hören wollen.
> Es war eher in der Nähe von CP/M anzusiedeln. Und hier spielte die
> Dateikompatiblität zu CP/M eine Rolle.
Bis DOS2.0. Seitdem wird diese Rolle von 'Inkompatibilität' gespielt.
> Das Zeilenende mit CRLF zu markieren ist auch keine Eigenschaft von
> CP/M, sondern einen Übereinkunft von Programmen und Geräten, die
> unter CP/M verwendet worden.
In Worten: Hirnlose Abwärtskombatibilität zu etwas, was damals schon
tot war (auch CP/M war mit hoher Sicherheit bloß abwärtskompatibel zu
etwas anderem). \r ist ein _Steuerzeichen_, \n in C ein syntaktischer
Trenner. Außerdem noch ein Steuerzeichen, nur ist jemand zwischendrin
mal aufgefallen, daß 'Wagenrücklauf' und 'Zeilenvorschub' so häufig
zusammen gebraucht werden, daß es Sinn macht, diese Funktionen _in
einem Kommando_ zu vereinen. Tatsächlich kann der Computer das sogar
in den weitaus meisten Fällen vollkommen alleine machen.
> Und warum C neben Binärdateien gerade zweidimensionale char-Felder
> mit Inband-Signaling und fehlenden direkten Zugriffsmöglichkeiten
> unterstützt, ist mir bis heute noch unklar.
Wie bereits gesagt: Listen von (Zeichen-)listen sind ein ziemlich
flexibles Format und vor allem eines, daß 'menschlichen' Gewohnheiten
näherliegt, als der (zum Scheitern veurteilte) Versuch, 'sowas' auf
eine unzureichende Simulation einer zweidimensionalen Matrix
abzubilden.
Das könnte aber vielleicht auch an der Matrix liegen, die lediglich
das Mißvergnügen hat, die einzige bekanntere mathematische
Datenstruktur zu sein. Das darf man ihr aber nicht wirklich
vorwerfen. :->
--
near
distant
Irgendwie scheinst Du an nicht sauber funktionierenden Programmen Deinen
Spaß zu haben.
Dieses Ei ist nun behoben (hoffe ich), ich weiß allerdings nicht, wie viele
immer noch lauern.
--
Frank Klemm
>> Es war eher in der Nähe von CP/M anzusiedeln. Und hier spielte die
>> Dateikompatiblität zu CP/M eine Rolle.
>
>Bis DOS2.0. Seitdem wird diese Rolle von 'Inkompatibilität' gespielt.
>
Ja. Und dann spielte die Kompatiblität zu DOS 1.0 eine Rolle.
Und bei 3.0 dann die zu DOS 2.0. Das hängt alles an einem Faden.
>> Das Zeilenende mit CRLF zu markieren ist auch keine Eigenschaft von
>> CP/M, sondern einen Übereinkunft von Programmen und Geräten, die
>> unter CP/M verwendet worden.
>
>In Worten: Hirnlose Abwärtskombatibilität zu etwas, was damals schon
>tot war (auch CP/M war mit hoher Sicherheit bloß abwärtskompatibel zu
>etwas anderem). \r ist ein _Steuerzeichen_, \n in C ein syntaktischer
>Trenner. Außerdem noch ein Steuerzeichen, nur ist jemand zwischendrin
>mal aufgefallen, daß 'Wagenrücklauf' und 'Zeilenvorschub' so häufig
>zusammen gebraucht werden, daß es Sinn macht, diese Funktionen _in
>einem Kommando_ zu vereinen. Tatsächlich kann der Computer das sogar
>in den weitaus meisten Fällen vollkommen alleine machen.
>
Ich glaube, daß Computer heutzutage im wesentlichen aus Rücksichten
auf Kompatiblität zu irgendwas anderem bestehen. Sie hat Vorteile und
Nachteile. Die Vorteile sind eine gewisse Interoperablität (stell' Dir vor,
jeder würde machen, was ihm gerade als optimal in den Sinn kommt), Nachteile
sind eben, daß Designfehler jahrzehntelang mitgeschleppt werden.
Bei Textformaten hat man sich auf relativ wenig solche Kompatibitätsketten
geeinigt, bei Bildformaten sieht es schlechter aus.
Und wenn man sich auf '\n' oder '\0' überall hätte einigen können (die '\0'
ist IMHO natürlicher als '\n'), dann hätte man dieses Problem zwar nicht,
aber dann würde vielen merken, daß auch das nicht das non-Plus-Ultra ist.
--
Frank Klemm
Korrekterweise:
,--- (man popen)
| The command argument is a pointer to a null-terminated
| string containing a shell command line. This command is
| passed to /bin/sh using the -c flag; interpretation, if
| any, is performed by the shell. The mode argument is a
| pointer to a null-terminated string which must be either
| `r' for reading or `w' for writing.
`---
--
2.4.5 in drivers/nubus/nubus.c:
(777): Bwahahahaha...
(782): Even more evil laughter...
http://rebo...@durchnull.de
strlen zum Beispiel müsste deutlich komplizierter sein...
--
> Code, der zum Verständnis Dokumentation braucht, ist meistens Käse.
Na ja, sowas kann man wenigstens noch essen. In Verbindung mit
Spaghetti-Code ist das doch was Feines.
Wirklich unschön wäre Maschinenkot. [Wilfried Krueger in dcsn]
>> Binäres Lesen Text lesen Fehler "Bad Args"
> [Viele Beispiele gelöscht]
>> Möchte man aus einer Datei binär lesen, dann benutzt man
>> fopen (name, "rb");
>> Das Äquivalent bei Lesen aus einer Pipe wäre
>> popen (name, "rb");
>> Leider geht das unter Linux nicht. Was soll der Schwachfug?
>> Wie mache ich portables Programmieren so schwer wie möglich oder
>> was ist das Ziel, was ich hier nicht M$ anlasten kann und will???
> Da fragst Du am besten MS, was der Schwachfug soll. Unter UNIX gibt es
> keine blödsinnige Unterscheidung zwischen Textdateien und binären Dateien.
Es stimmt zwar, daß diese Unterscheidung unter Unix entfällt
- ich finde es auch sinnvoll -, aber das "b"-Flag ist keine
windows-Erfindung, sondern schon ein mitbringsel von der
Sprache C her.
Also eher über den ANSI-C-Standard meckern...
> Die gibt es nur bei Windows.
Quatsch.
Schau in K&R nach, da sit das "b"-Flag erwähnt.
> Bei fopen() wird das "b" zwar großzügig
> akzeptiert, aber ignoriert. Bei fopen() wurde das Flag wohl akzeptiert, um
> dem ISO C standard gerecht zu werden.
Eben. C-Standard halt.
> popen() ist dagegen in ISO C nicht
> definiert (sondern POSIX). SUSV2 sagt unter anderen dazu:
Eben.
[...]
> Jaja, Windows ist unästhetisch, da es unbedingt zwischen Textdateien und
> Nicht-Textdateien unterscheiden wollte.
> Was spricht gegen ein
> #ifdef WINDOWS
> #define RB "rb"
> #define WB "wb"
> #else
> #define RB "r"
> #define WB "w"
> #endif
was spricht dagegen, Windows völlig zu ignorieren?
Ciao,
Oliver
--
"Von mir aus kann der Staat die Steuern ruhig erhöhen, von mir ist ja doch
nichts zu holen." geht Hand in Hand mit:
"Von mir aus kann der Staat mich ruhig belauschen, ich habe ja nichts zu
verbergen.
Deswegen passiert das auch nicht.
--
near
distant
> Und wenn man sich auf '\n' oder '\0' überall hätte einigen
> können (die '\0' ist IMHO natürlicher als '\n'), dann hätte
> man dieses Problem zwar nicht, aber dann würde vielen merken,
> daß auch das nicht das non-Plus-Ultra ist.
Wie sieht es eigentlich mit EOF (^Z) und Textmode aus
(Textmode-Emulation unter nicht-CP/M-Abkömmlingen)? Im Textmode
beendet ja EOF den Kanal (auch wenn noch Daten anstehen), im Binärmode
wird es ignoriert.
Im übrigen finde ich es schade, wenn immer nur von 0x0A oder 0x0D 0x0A
geredet wird, aber 0x0D als Zeilenende (Mac) unberücksichtigt bleibt.
Damit hatte ich unter Unix mit Postscript-Verarbeitung (wo man noch
0x04 rausfiltern durfte ... ^D ... :-( ) zu tun.
So long,
-+- Dirk -+-
Ähnlich war auf einigen 8-Bit-Systemen dafür Bit 7 reserviert.
"Hallo" wurde dort als 'H', 'a', 'l', 'l', 'o'+0x80 kodiert.
Spart ein Byte.
Auch gab es einige PC-Programme, die fehlerhafterweise statt 0D+0A
ein 0A+0D geschreiben haben.
P-Strings waren auch noch viel im Einsatz.
--
Frank Klemm
--
Frank Klemm
Weil es sich nicht um eine Plattform, sondern um eine Krankheit handelt?
Die eigentlich Frage ist, wieso du unter Windows entwickelst.
> Ich persönlich komme mit der Entwicklungsoberfläche sehr gut zurecht.
Mein Windows hat keine Entwicklungsoberfläche.
Felix
> Weil es sich nicht um eine Plattform, sondern um eine
> Krankheit handelt?
von den Unzulänglichkeiten her gesehen ist zur Zeit jedes
Betriebssystem mehr oder minder eine Krankheit.
> ist eher, warum ich andere OS unterstütze. Der Aufwand für die Unterstützung
> von 95/98/ME/NT/2000/XP ist weit geringer als die Unterstützung
> von HPUX/Solaris/Ultrix/Digital Unix.
Wieso? Weil Du bei Unix auf die Großkleinschreibung in #include achten
mußt? Oder weil Du nicht portabel programmierst? Wenn Windows zickt und
Du das unbedingt haben mußt, löt' Dir halt eine Abstraktionsschicht.
--
Matthias Andree
"They that can give up essential liberty to obtain a little temporary
safety deserve neither liberty nor safety." Benjamin Franklin
Hehe, das verspricht lustig zu werden.
Ich hol mal das Popcorn raus...
Fefe