Hallo
Ich möchte den Inhalt mehrere Dateinen vegleichen, brauche hier aber mal
hilfe in einfacher Form.
Vergleich von 2 dateien (byte für byte) und dann die ergebnis ausgabe in
einer 3. datei.
Sprache C(, oder C++)
könnt ihr mir helfen?
Danke
Bsp.
datei1.txt = Inhalt. 121212021
datei2.txt = Inhalt. 121212121
Ergebiss:
datei3.txt = Inhalt. 000000100
Du solltest mehr zu Menge und Format der Daten erzählen. Ist es immer
nur 1 Ziffernkolonne mit 9 Stellen? Kommt auch Text vor? Falls mehrere
Daten(-sätze) pro Datei, welche Trennzeichen werden verwendet? Einfaches
Konsolenprogramm oder Windows-Anwendung mit eigenem Fenster? usw.
Und wo ist das Problem? Schreib' eine Schleife, vergleiche den Inhalt
byte-weise (wenn man mal von ASCII ausgeht) und schreib' dann dein
Ergebnis in die Ausgabe.
Stehen die Zahlen in der Datei als binärer Wert, also z.B. 1 =
0b00000001, oder ASCII? Steht das 1/0 für gleich/ungleich oder für die
Differenz?
Für die Differenz könnte es in C so aussehen:
Ist von den C++ Heinis eigentlich noch keiner auf die Idee gekommen, den
ganzen ++ Sprachsumpf mal zu entschlacken? Das sah vorher ja schon so
geschwätzig aus wie Pascal. So wäre es schon lesbarer:
1
letstd::
2
{
3
intmain(){
4
ifstreami1("test1.txt");
5
ifstreami2("test2.txt");
6
ofstreamo("test3.txt");
7
8
transform(istreambuf_iterator<char>(i1),
9
istreambuf_iterator<char>(),
10
istreambuf_iterator<char>(i2),
11
ostreambuf_iterator<char>(o),[](chara,charb){
12
returnb-a;});}
13
}
Einen Haufen überflüssige Tastaturanschläge eliminiert!
@Max H
Das funktioniert so nicht. Entweder ist char signed, dann ist -1 ein
gültiges Zeichen oder es ist unsigned und dann kann es nie -1 sein.
Wenn du aber chr1 und chr2 als int definierst, kann es klappen.
fgetc hat nicht umsonst einen int als Rückgabewert.
Du solltest aber die -1 durch EOF ersetzen.
printf gibt bei %c Zeichen aus. Das bringt nicht viel, da die druckbaren
Zeichen (i.A) erst bei 32 beginnen. Ein %hhd wäre sinnvoller.
Was ist aber wenn file2 kürzer als file1 ist?
Die fehlenden fclose und den Test auf erfolgreiches Öffnen schieb ich
jetzt mal dem quick and dirty zu.
C-- schrieb:> Ist von den C++ Heinis eigentlich noch keiner auf die Idee gekommen, den> ganzen ++ Sprachsumpf mal zu entschlacken? Das sah vorher ja schon so> geschwätzig aus wie Pascal. So wäre es schon lesbarer:
Auf die Idee sind schon viele gekommen. Allerdings widerspricht das der
Anforderung, erweiterbar zu sein. Prinzipiell geht das zwar:
Aber davon ist dringend abzuraten, siehe
http://stackoverflow.com/questions/1452721 .
Da C++ erweiterbar sein soll, gibt es eben Dinge wie namespaces, damit
es bei der Verwendung vieler Komponenten (Libraries) keine
Überschneidungen gibt. Man muss die Dateien einzeln #include'n, weil es
im Gegensazu zu Pascal mehr als 5 Libraries gibt und das automatische
#include'n aller Libraries viel zu langsam wäre.
Um also eine universelle erweiterbare Sprache zu erhalten, muss man eben
öfter mal std:: eingeben. Das ist übrigens in quasi allen neueren
Sprachen auch so, in java muss man dinge wie "java.io." davorschreiben,
in ruby "Net.", und sogar in C behilft man sich mit prefixen, so fangen
zB alle Gtk-Funktionen mit "gtk_" an. Das ist der Preis, den man für
eine universelle Sprache zahlen muss. Ist ja schön dass das in Pascal
kürzer geht, aber dafür kann man da halt nicht so viel machen. Achja,
und zeig doch mal ein echtes Pascal-Programm was das in so kurz kann.
Dr. Sommer schrieb:> using namespace std;>> int main () {> ifstream i1 ("test1.txt");> Aber davon ist dringend abzuraten
Wobei man das natürlich nicht nur mit der groben Kelle global, sondern
auch lokal und spezifisch verwenden kann (und dann ist es, je nach
Kontext, nicht mehr böse).
Dr. Sommer (Gast) schrieb:
C-- schrieb:
>> Ist von den C++ Heinis eigentlich noch keiner auf die Idee gekommen, den>> ganzen ++ Sprachsumpf mal zu entschlacken? Das sah vorher ja schon so>> geschwätzig aus wie Pascal. So wäre es schon lesbarer:> Auf die Idee sind schon viele gekommen. Allerdings widerspricht das der> Anforderung, erweiterbar zu sein. Prinzipiell geht das zwar:
Ja, sowas meinte ich.
> Aber davon ist dringend abzuraten, siehe> http://stackoverflow.com/questions/1452721 .
Den Einwand verstehe ich nicht so ganz.
Lesen wir mal aus deinem Link:
"Everything works fine, you can call Blah() from Foo and Quux() from Bar
without problems. But one day you upgrade to a new version of Foo 2.0,
which now offers a function called Quux(). Now you've got a conflict:
Both Foo 2.0 and Bar import Quux() into your global namespace."
Wer hindert denn den Compiler daran hierfür einfach eine Warnung
auszuwerfen? Wenn er plötzlich mehrere Funktionen gleichen Namens
findet, wäre es doch ein leichtes den Anwender mit einer Warnung dazu zu
bewegen, entsprechende Funktionen EINZELN dann mit einem "std:: .." zu
versehen und dadurch einem möglichen Konflikt aus dem Weg zu gehen.
Wo also soll das Problem sein? Warum den Quelltext unnütz aufblähen,
wenn es gar nicht sein müsste?
Oder wie wäre es mit dieser Methode die er hier verwendet hat:
Beitrag "[C++] Array verliert Werte"
Warum nicht so?
> Ist ja schön dass das in Pascal> kürzer geht, aber dafür kann man da halt nicht so viel machen. Achja,> und zeig doch mal ein echtes Pascal-Programm was das in so kurz kann.
Nein, ich sagte doch bereits, Pascal ist noch geschwätziger.
C-- schrieb:> Wer hindert denn den Compiler daran hierfür einfach eine Warnung> auszuwerfen?
Das zB:
Library A:
1
namespaceLibA{
2
voidfoo(inta);
3
voidbar(inta);
4
}
Library B:
1
namespaceLibB{
2
voidbar(chara);
3
}
Programm:
1
usingnamespaceLibA;
2
usingnamespaceLibB;
3
4
intmain(){
5
bar(27);
6
}
Ist das jetzt eine Warnung? Fehler? Oder doch Absicht? Besonders spaßig
wenn LibA::foo erst in einer späteren Version hinzukam. Das kann der
Compiler nicht wissen. Daher "using namespace" gleich bleiben lassen.
C-- schrieb:> Oder wie wäre es mit dieser Methode die er hier verwendet hat:
Ja, das geht. Wird auch zB in Java so gemacht.
C-- schrieb:> Nein, ich sagte doch bereits, Pascal ist noch geschwätziger.
Uhps.
.. Compiler message: WARNING! You have used function
>>>>>> bar (27); <<<<<<
in line .. This function seems to resist in more than ONE Namespaces you
included in your sourcecode! Please use scope Operator :: to clear this
out!
error; no source code compiled
Nach dem Tod von P. Ostrich bleibt für mich eigentlich nur noch folgende
Frage über.
Wenn:
>datei1.txt = Inhalt. 121212021>datei2.txt = Inhalt. 121212121>Ergebiss:>datei3.txt = Inhalt. 000000100
ergibt, was soll dann bei:
datei1.txt = Inhalt. 121212121
datei2.txt = Inhalt. 121212021
herauskommen?
Etwa
datei3.txt = Inhalt. 000000100
?
Nebenbei bemerkt: Ich finde es immer wieder toll, wie aus völlig
unzureichenden "Ergüssen" -zig Zeilen Code entstehen.
Dr. Sommer (Gast) schrieb:
C-- gast schrieb:
>> Oder wie wäre es mit dieser Methode die er hier verwendet hat:
1
usingstd::cout;
2
usingstd::cin;
3
usingstd::endl;
4
usingstd::flush;
5
usingstd::string;
6
usingstd::ifstream;
7
usingstd::ofstream;
8
usingstd::istringstream;
9
usingstd::istream_iterator;
10
11
// ...
> Ja, das geht. Wird auch zB in Java so gemacht.
Gut. Nur warum insgesamt so umständlich wie hier etwas spezielles zu
erlauben bzw. zu konkretisieren (mit vielen Ausnahmen) anstatt etwas
allgemein zu erlauben (using std;) und NUR im Konfliktfall (Compiler
Warning) explizit diese Allgemeinheit für eine bestimmte Funktion dann
zu widerrufen und damit die Konkretisierung zu verlanden (zu erzwingen)
Bsp. Libxy::foo(), um Zweideutigkeiten auszuschließen?
Wie oben gezeigt würden Quelltexte um einiges besser lesbar sein bei
gleichzeitig weniger Schreibaufwand. Warum also der Zwang so umständlich
C++ Quelltexte zu schreiben?
> Das ist aber schlecht, weil dann eine Menge korrekter C++ Code nicht> mehr kompilierbar wäre.
Für alten Code würde sich doch gar nichts ändern. Der ist ja in der Form
lib::function(), also eindeutig und wird nach wie vor compiliert. Neuer
C++ Code, der vereinzelte Mehrdeutigkeiten hätte, könnte dann wie hier
geschrieben werden
Beim Compilieren würde klar, es gibt mindestens eine Funktion (hier
ifstream()), die nicht eindeutig zuzuordnen wäre. Jetzt könnte man den
Programmierer dazu anhalten nach einem Vorrangschema nur diejenigen
Funktionen zu konkretisieren, die von der Regel abweichen. Also z.B.
eher spezielle Funktionen im Namespace mittels Scope zu kennzeichnen,
wie hier
LibA::ifstream ("a");
Der Rest bleibt wie gehabt.
Ja, das funktioniert so sogar. Leider kann es so immer noch
Überraschungen mit Overloads geben, wie im Beispiel in
Beitrag "Re: Dateiinhalte vergleichen" wenn
LibA::bar nachträglich hinzukam. Der Code ist korrekt und muss es auch
bleiben (=> kein Compiler Fehler) aber dennoch wird plötzlich die
falsche Funktion aufgerufen. Das Problem entsteht, wie im
Stackoverflow-Artikel erklärt, wenn Funktionen nachträglich hinzukommen.
Dann muss man allen die Libraries verwendenden Code anpassen, um die
neuen Uneindeutigkeiten zu beseitigen - schlecht. Da lieber konsistent
überall LibA:: davorschreiben, dann ist es eindeutig und wird es auch
bleiben.
Das nächste Problem ist dass der "std" namespace jede Menge interne
Bezeichner enthält. Die will man eigentlich auch nicht im globalen
namespace haben.
Außerdem wird der Code durch explizite Namespaces sogar lesbarer. z.B.:
1
intmain(intargc,char*argv[]){
2
Gtk::Mainm(&argc,&argv);// Aha, hier wird das Gtk-Main-Objekt angelegt. Gehört zur Gtk-Library.
3
}
vs.
1
usingnamespaceGtk;
2
/* ... viel code ... */
3
intmain(intargc,char*argv[]){
4
Mainm(&argc,&argv);// Main?? Was soll das sein? Nicht lesbar.
5
}
In kurz: Mit "using namespace std;" handelt man sich nur Probleme ein.
Und ein paar mal "std::" einzugeben ist kein Beinbruch. Das kannst du
dir ja auf eine Schnelltaste legen wenn es gar zu schlimm ist.
Hallo zusammen.
ich hatte absichtlig erstmal klein gefragt, da ich mir den rest, was ich
vor habe auch welcher erweitern könnte.
daher die Frage den Inhalt Byteweise zu vergleichen und das in ein
ergebni (datei) zu schreiben.
Die Dateien können auch Hex Datein/Werte enthalten. Bzw einfach Ascii
Zeichen. und dies möchte ich dann mal addieren, Vergleichen, oder sonst
welche Mathematischen Funktionen mit machen
Die Länge variiert
Also Kurz:
byte 1 von Datei 1 lesen und mit bte 1 Von Datei 2 verlgiechen (bzw.
addieren oder so)
Dann Ergebnis in Byte 1 der Datei 3 schreiben
Am liebsten wäre es mir auch in C, aber C++ geht auch
Aer dann werd ich mal mit dem gegebenen vesuchen was zu machen
Dank euch allen schonmal
Immer noch unklar!
Der Begriff "vergleichen" sagt Garnichts aus!
Die Addition von 1 und 2 ergibt 3.
Die Addition von 250 und 9 ergibt ebenfalls 9 - hoppla, wie informativ.
P. Ostrich schrieb:> Am liebsten wäre es mir auch in C, aber C++ geht auch>> Aer dann werd ich mal mit dem gegebenen vesuchen was zu machen> Dank euch allen schonmal
Die Frage hättest Du dir doch wirklich sparen können, es sei denn du
hast auf eine komplette Lösung deiner Hausaufgabe gehofft.
"compare two files in C" liefert doch unzählige hits in google, als
erstes
http://www.c4learn.com/c-programs/c-program-to-compare-two-textdata-files-in-c-programming.html
Da du C willst, kanst Du C oder möchtest es lernen -- dann ist es doch
wohl nicht schwer den Code anzupassen.
Klingt wie nach Hausaufgabe. Kein normal denkender Entwickler nimmt für
sowas C, sondern a) schon fertige tools wie diff.... oder macht das mit
einem Einzeiler Perl oder sonstiger Scriptsprache.
Und wer da mit barok-verbloatetem C++ ankommt sollte besser auf
Schuhverkäufer umschulen.
Oben: "Ich verkürze mal den C++-Code" der danach genau verbloatet ist.
Erst mal eine Tonne includes für eine Trivialaufgabe. LOL. Lasst die
Finger von den Rechnern und schult auf Erntehelfer o.ä um.
Max H. schrieb:> Stehen die Zahlen in der Datei als binärer Wert, also z.B. 1 => 0b00000001, oder ASCII? Steht das 1/0 für gleich/ungleich oder für die> Differenz?>> Für die Differenz könnte es in C so aussehen:>
1
intmain()
2
>{
3
>charchr1,chr2;
4
>FILE*file1,*file2,*file3;
5
>file1=fopen("datei1.txt","r");
6
>file2=fopen("datei2.txt","r");
7
>file3=fopen("datei3.txt","w");
8
>
9
>chr1=getc(file1);
10
>chr2=getc(file2);
11
>while((chr1!=-1)&&(chr2!=-1))
12
>while((chr1!=-1))
13
>{
14
>fprintf(file3,"%c",chr2-chr1);
15
>chr1=getc(file1);
16
>chr2=getc(file2);
17
>}
18
>return0;
19
>}
Hi
Also dies kann ch schon so nutzen und ändern, wie ich es brauche.
2 Probleme / Fragen jedoch noch:
1.Verstehe nicht, warum die While-schleife ei zeichen nach dem anderen
absucht ohne das hochgezählt wird.
2. wenn ich das durch ein größeses file laufen lasse bekomme ich nicht
das ganze file bearbeitet.
danke euch allen
P. Ostrich schrieb:> 1.Verstehe nicht, warum die While-schleife ei zeichen nach dem anderen> absucht ohne das hochgezählt wird.
Getc liefert beim ersten Aufruf das erste Zeichen, beim zweiten aufruft
das
Zweite usw., die getc() Funktion zählt also von alleine weiter.
P. Ostrich schrieb:> 2. wenn ich das durch ein größeses file laufen lasse bekomme ich nicht> das ganze file bearbeitet.
So wie er aktuell dasteht orientiert er sich an der Länge von
"datei1.txt"
@DirkB: Doch hab ich, aber mit %c muss ich schon arbeiten. jedenfalls
falls ich mit einem Hex File arbeite, was ich gerade mal probiert habe.
-> hab es mit einer XOR vergleich probiert
1
fprintf(file3,"%c",chr2^chr1);
Und wegen dem hochzähle wusste ich nicht das getc immer das nächste
zeichen nimmt.
@max.H Ne an der Länge von Datei1.txt liegt es nicht. sind exakt gleich
lang
P.S.: Ich habe mal zwei ca. 10kb große dateien genommen, es kommen aber
immer nur als Datei 3 eine maximal 2kb große datei raus
Danke Alex, ich möchte das schon Programmieren.
am Ende kommen noch mehrere Teile zum Code dazu, daher bringt es nichts
mit einem aleinstehenden Tool etwas zu machen
Wenn du Vergleichen willst, dann schreib auch einen Vergleich.
XOR ist kein Vergleich an sich. XOR verknüpft 2 Werte nach einer
bestimmten Vorschrift auf Bitebene.
Maachs nicht so kompliziert. Du sagst ja auch umgangssprachlich: Wenn ds
Zeichen aus der Detei 1 größer ist als das Zeichen aus der Datei 2. Von
XOR ist da erst mal nicht die Rede, sondern von vergleichen.
> P.S.: Ich habe mal zwei ca. 10kb große dateien genommen, es kommen aber> immer nur als Datei 3 eine maximal 2kb große datei raus
Ja, das nennt man programmieren. Und das muss man lernen. Fehler zu
suchen gehört da genauso mit dazu. Und auch die Technik(en), die man
benutzen kann, um Fehler zu finden.
Das wird dir noch oft passieren, dass ein Code erst mal nicht das macht,
was du gerne hättest. Wenn du programmieren willst, dann fang beim
Lernen vorne an und nicht mitten drinnen. Am besten mit einem
ordentlichen Lehrbuch.
>> Wenn du Vergleichen willst, dann schreib auch einen Vergleich.> XOR ist kein Vergleich an sich. XOR verknüpft 2 Werte nach einer> bestimmten Vorschrift auf Bitebene.
Hi. Ja da hast du recht, aber so kann ich auch schauen, wenn das
Ergebnis ungleich 0 ist, dann ist eine differenz vorhanden..
Ich hab das XOR genommen, weil ich das in einem anderen
>> P.S.: Ich habe mal zwei ca. 10kb große dateien genommen, es kommen aber>> immer nur als Datei 3 eine maximal 2kb große datei raus>> Ja, das nennt man programmieren. Und das muss man lernen. Fehler zu> suchen gehört da genauso mit dazu. Und auch die Technik(en), die man> benutzen kann, um Fehler zu finden.> Das wird dir noch oft passieren, dass ein Code erst mal nicht das macht,> was du gerne hättest. Wenn du programmieren willst, dann fang beim> Lernen vorne an und nicht mitten drinnen. Am besten mit einem> ordentlichen Lehrbuch.
habe es beim Fileöffnen mit denn Attributen bissel gespielt. leider muss
man da immer erst im Nets suchen. eine vernünftige Hilfe, die ich in
code::Blocks oder so einbilden kann wäre super
Aber so ging es
1
file3=fopen("3.txt","wb")
Jetzt hab ich einen weiteren schritt offen.
ich will ein bestimmtes zeichen aus dem 1 File mit einem bestimmten
zeichen aus den 2. File vergleichen
hehe lustig.
genau daran bin ich jetzt auch hängen geblieben.
wollte erst hiermit die datei länge zählen:
1
longcounter_max=0;
2
3
fseek(file1,0L,SEEK_END);
4
printf("Die Datei ist %ld Bytes gross!!\n",ftell(file1));
5
6
//Dateigröße in var counter_max speichern
7
counter_max=(ftell(file1));
Und jetzt halt noch die durchführung der vergleiche.
Z.B.
alle geraden zeichen auslesen: Also das erste, dritte, fünte usw.
oder immer in 10er Schritten