Vorsichtige Behauptung: Mit den streams wirst du da nicht so einfach
glücklich. Die Dinger sind für formatierte Text-Operationen gedacht. Das
heißt, dass alles was gelesen wird, erstmal durch die Mangel gedreht
wird und irgendwelche Character-Encodings aus der locale angewendet
werden usw.
Um eine Datei garantiert unverändert einzulesen müsstest du schon mit
ios::binary und istream::read arbeiten oder ein Guru bezüglich der Spec
sein, die da zB sagt
1
When reading characters, std::istream_iterator skips whitespace by default (unless disabled with std::noskipws or equivalent), while std::istreambuf_iterator does not. In addition, std::istreambuf_iterator is more efficient, since it avoids the overhead of constructing and destructing the sentry object once per character.
Wilhelm M. schrieb:> Du brauchst einen istreambuf_iterator<char>.
Auf welchen Teil der Spec beziehst du dich da, dass der streambuf
garantiert "unverfälschte" Daten enthält?
Ich lese da
1
The character representation and encoding in the controlled sequence may be different from the character representations in the associated sequence
Im Speziellen
1
Data read in from a text stream is guaranteed to compare equal to the data that were earlier written out to that stream only if all of the following is true: ...
1
A binary stream is an ordered sequence of characters that can transparently record internal data. Data read in from a binary stream always equals to the data that were earlier written out to that stream. Implementations are only allowed to append a number of null characters to the end of the stream.
Ist da garantiert, dass diese Nullen nicht schon im Buffer auftauchen?
zer0@away schrieb:> Vorsichtige Behauptung: Mit den streams wirst du da nicht so einfach> glücklich.
Danke für deine Antwort. Jetzt hab ichs mit unformatiertem input. Das
müsste ja jetzt auch im Textmode gehen und das lineending der Platform
nehmen?
cat.cpp
1
#include<fstream>
2
#include<iostream>
3
#include<string>
4
usingnamespacestd;
5
intmain(intargc,char**argv){
6
if(1==argc){
7
for(strings;getline(cin,s);){
8
cout<<s<<endl;
9
}
10
}else{
11
for(size_tn=1;n<argc;++n){
12
autoa=ifstream(argv[n]);
13
for(strings;getline(a,s);){
14
cout<<s<<endl;
15
}
16
}
17
}
18
return0;
19
}
Falls es jemand braucht, im Anhang cat.exe für Windows 32.
Beim Lesen eines char über einen input_iterator wird sämtlicher
Whitespace übersprungen.
Die Verwendung von getline kann Probleme bei überlangen Textzeilen
machen.
Ich würde es so machen:
Z. Klatscher schrieb:> Das> müsste ja jetzt auch im Textmode gehen und das lineending der Platform> nehmen?
Die Frage wäre, ob du das willst:
1
On systems like MS-DOS that distinguish between text and binary files, cat normally reads and writes in binary mode. However, cat reads in text mode if one of the options -bensAE is used or if cat is reading from standard input and standard input is a terminal.
https://www.gnu.org/software/coreutils/manual/html_node/cat-invocation.html#cat-invocation
Das normale Verhalten ist, die Datei unverändert zu lassen. Man weiß
nie, auf welcher Platform welche Datei geschrieben wurde und auch nicht,
ob es eine Binärdatei ist. Das resultierende Chaos sieht man immer,
wenn man Dateien zwischen Posix und Windows hin- und herschiebt.
Ich würde ein cat, dass per Default Dateien verändert, nicht gerade
begrüßen... >:
Heiko L. schrieb:> Ich würde ein cat, dass per Default Dateien verändert, nicht gerade> begrüßen... >:
Ich auch nicht. Die Hauptaufgabe von cat (wenn auch oft für anderes
benutzt) ist ja eigentlich, mehrere Dateien zu einer zusammenzufügen
(conCATenate). Und das sollte natürlich nicht nur mit Text-, sondern
auch mit Binärdateien sauber funktionieren.
Wozu das ganze? Cat gibt es doch schon, wenn du es brauchst, nimm doch
ein bestehendes. Unter windows kann man vergleichbares zeug über ein
paar Umwege übrigens auch mit nativen Tools machen.
Dateien zusammensetzen, cat.bat:
1
@ECHO OFF
2
:Loop
3
IF "%1"=="" GOTO Continue
4
type "%1"
5
SHIFT
6
GOTO Loop
7
:Continue
1
cat.bat a.txt b.txt
Consolen Eingabe auf console ausgeben: (nicht das selbe wie stdin,
windows hat nichts äquivalentes zu /dev/stdin bzw. /dev/fd/0 btw.
/proc/self/fd/0, geht also nicht mit dem Output des Vorgängerprogramms.)
1
type CON
Klar, unter Windows ist das alles etwas Komplexer, zum einfachen
Scripting echt nicht zu gebrauchen, aber wenn man was richtiges will,
muss man halt auch das echte & gute zeug nehmen, statt den Windows mist.