ubuntu--anfaenger
(Themenstarter)
Anmeldungsdatum: 12. Oktober 2013
Beiträge: 1088
Wohnort: Belgien
|
Vielen Dank für die Antworten, Ich habe wohl etwas Verwirrung gestiftet 😬 dingsbums Du weisst nicht, in welchen Pfaden sich Original und Backup befinden? Bedenklich.
Doch natürlich weiss ich immer wo die Dateien sich befinden, ich will die nur nicht jedesmal in dem Verzeichnis reinkopieren wo sich das Programm zum vergleichen befindet(also die a.out) unbuntuS12 Ich weiß, es scheint hier drum zu gehen, sich programmiertechnisch auszuprobieren,
Ja so kann mann das nennen, ich hatte mir gedacht wenn ich es schaffe ein template so zu bauen das es bytes liesst,kann ich alles mögliche vergleichen,png,jpg,bin,usw.. das klappt auch sehr zuverlässig, solange die Dateien im selben Verzeichnis wie das Programm sind. rklm
Dann nimmst Du einfach das Kommandozeilenprogramm cmp. Jemand anders hat sich schon ausgiebig den Kopf über das Problem zerbrochen und ein allgemeines Tool dafür geschrieben, das das Problem effizient löst.
Ja das macht das bestimmt besser als mein kleines Programm, aber so lerne ich nicht wie mann Pfade richtig angibt, wenn ich zb mal einem prgrm versuchen würde das einen Text einliesst den formatiert mit ofstream ausgibt(timestamp,Temperaturwerte oder Listen), hätte ich wieder das gleiche Problem, klar ich kann dann die Ausgabe von ofstream mit mv ins richtige Verzeichnis ablegen. user_unknown Du kannst natürlich bloß den Namen eingeben, und den Rechner nach allen Dateien dieses Namens suchen lassen,
Das wäre genau mein Ziel gewesen,und dann vergleichen aber wenn das halt so kompliziert ist
Vergleicht also doch mehr als das letzte Zeichen.
Ich poste es nochmal und füge Komentare ein,ich hab das Gefühl das nicht verstanden wird was das Programm tut.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 | #include <iostream>
#include <vector>
#include <fstream>
using namespace std;
template<typename T> // Type t, eigener Type
char* wie_bytes(T& i) // behandele t wie eine byte Folge
{
void* addr = &i; // finde die Adresse des ersten bytes
return static_cast<char*>(addr); // behandle den Speicher wie bytes
}
int main()
{
cout << "Erste Datei: " << '\n';
string name;
cin >> name; // Der Name der Datei dessen Inhalt verglichen werden soll
ifstream istr(name.c_str()); // Ein ifstream mit Variable istr wir geöffnet und von einem c string eingelesen
if(!istr){cerr << "Kann Datei 1 nicht lesen!!!" << '\n'; //Falls ich mich vertippt habe, oder der Dateiname nicht existiert,beende das Programm(mann könnte noch eine exepetion werfen)
return 1;
}
vector<int>eins; //ein Vector öffnen
int i; // wo reingeschrieben wird
while(istr.read(wie_bytes(i), sizeof(int))) //Ein while loop liest istr so lange ein bis das Ende erreicht ist(sizeof())
eins.push_back(i); // Das Eingelesene wird mit push_back im Vector gedrückt
cout << "Zweite Datei: " << '\n';
cin >> name; // Das gleiche Prozedere wie mit der ersten Datei
ifstream uistr(name.c_str());
if(!uistr){cerr << "Kann Datei 2 nicht lesen!!!" << '\n';
return 2;
}
vector<int>zwei;
int t;
while(uistr.read(wie_bytes(t), sizeof(int)))
zwei.push_back(t);
if(i==t){
cout << "Dateien sind gleich!!!" << endl;
} //Die kompletten bytes der beiden Dateien werden verglichen
else
cout << "Dateien ungleich" << endl;
return 0;
}
|
Dann noch zum Testen ein Trick: Das Lesen von Stdin kann über eine Pipe geschehen und so dumme Tipparbeit eliminieren:
Das funktioniert bei mir nur für Identische Kopien:wenn mann von einer Quelle kopiert, klappt das. aber nicht wenn mann die Dateien zb von Hand erstellt sprich: nano aha(schreibt mann "hallo" rein) nano oha(schreibt mann "hallo" rein) die Dateien sind ungleich, obowl die genau gleich sind.
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
ubuntu--anfaenger schrieb: user_unknown Du kannst natürlich bloß den Namen eingeben, und den Rechner nach allen Dateien dieses Namens suchen lassen,
Das wäre genau mein Ziel gewesen,und dann vergleichen aber wenn das halt so kompliziert ist
Es ist nicht so kompliziert - es ist nur viel Arbeit, und ineffizient, wenn man weiß wo die 2 Dateien liegen. Dabei spielt weniger eine Rolle (außer man gibt sich krampfhaft Mühe es anders zu machen), wo das Programm liegt, welches Du ausführst, als vielmehr in welchem Verzeichnis Du bist, wenn Du das Programm startest. Für 99% aller Programme gilt, dass wenn sie im Pfad /foo/bar/bin liegen und Du damit eine Datei "barfuss" öffnest, es die Datei "barfuss" nur dann in /foo/bar/bin sucht, wenn Du das Programm aus /foo/bar/bin gestartet hast. Beim Entwickeln und Testen ist beides zwar oft identisch - in der praktischen Arbeit ist es aber unpraktisch in das Verzeichnis wechseln zu müssen, in dem das Programm liegt. Um es nur mit dem Namen aufzurufen und ohne vollst. Pfad verschiebt man es in (s)einen bin-Ordner den man in den Pfad aufnimmt (~/bin oder /usr/local/bin oder /opt/bin). Wenn Du die Datei anhand des Namens suchst, dann hast Du einerseits damit zu tun, dass es mehrere Dateien dieses Namens geben kann, dass Du auf der Suche auf Verzeichnisse stößt, die Du gar nicht lesen darfst, dass es sehr viele zu durchsuchende Verzeichnisse gibt, dass das sonst niemand so macht, um 5 zu nennen, die mir spontan einfallen.
Vergleicht also doch mehr als das letzte Zeichen.
Ich poste es nochmal und füge Komentare ein,ich hab das Gefühl das nicht verstanden wird was das Programm tut.
| template<typename T> // Type t, eigener Type
char* wie_bytes(T& i) // behandele t wie eine byte Folge
{
void* addr = &i; // finde die Adresse des ersten bytes
return static_cast<char*>(addr); // behandle den Speicher wie bytes
}
|
Ah, ja, das habe ich verdrängt. Das ist ja grausamer Code - schreibt man so wirklich c++? Hat mit statischer Typisierung nur wenig zu tun, oder? void*, T&, int, byte, char - alles geht durcheinander und ist das gleiche :schüttel: . Aber darum soll es nicht gehen.
Dann noch zum Testen ein Trick: Das Lesen von Stdin kann über eine Pipe geschehen und so dumme Tipparbeit eliminieren:
Das funktioniert bei mir nur für Identische Kopien:wenn mann von einer Quelle kopiert, klappt das. aber nicht wenn mann die Dateien zb von Hand erstellt sprich: nano aha(schreibt mann "hallo" rein) nano oha(schreibt mann "hallo" rein) die Dateien sind ungleich, obowl die genau gleich sind.
Kannst Du das beweisen? Mit cmp und diff vielleicht - die bereits vorgeschlagen wurden, evtl. mit ls -l? Und wieso braucht man nano, um "hallo" nach "aha" zu schreiben? | echo hallo > aha
echo hallo > oha
|
Nano, dieses aufgeblasene Übermonster von einem Editor! Und was heißt "sind ungleich"? Vielleicht arbeitet Dein Programm doch falsch. | t201:~/proj/mini/forum > echo hallo > oha
t201:~/proj/mini/forum > echo hallo > aha
t201:~/proj/mini/forum > cat aha oha
hallo
hallo
t201:~/proj/mini/forum > echo -e "aha\noha" | ./datvgl
Erste Datei:
Zweite Datei:
Dateien sind gleich!!!
|
Scheint nicht so.
|
ubuntu--anfaenger
(Themenstarter)
Anmeldungsdatum: 12. Oktober 2013
Beiträge: 1088
Wohnort: Belgien
|
user_unknown Um es nur mit dem Namen aufzurufen und ohne vollst. Pfad verschiebt man es in (s)einen bin-Ordner den man in den Pfad aufnimmt (~/bin oder /usr/local/bin oder /opt/bin).
Das Programm soll aus Documents gestartet werden, das ist ok so.Das Problem ist ja wie es die Dateien findet,wenn zb eine Datei aha in /home/user/Desktop liegt, und eine Datei oha in /home/user/Documents liegt. Mein Vorhaben ist ja anscheinend nicht umzusetzen, und habe ja schon gute Alternativen angeboten bekommen cmp, diff.Ansonsten mach ich es dann so:echo -e "aha\n/tmp/eho" | ./datvgl
Wenn Du die Datei anhand des Namens suchst, dann hast Du einerseits damit zu tun, dass es mehrere Dateien dieses Namens geben kann, dass Du auf der Suche auf Verzeichnisse stößt, die Du gar nicht lesen darfst, dass es sehr viele zu durchsuchende Verzeichnisse gibt, dass das sonst niemand so macht, um 5 zu nennen, die mir spontan einfallen.
Ich frage mich jetzt gerade wie die Suchfunktion von Nautilus das macht,der findet auch gesperrte Dateien.
Ah, ja, das habe ich verdrängt. Das ist ja grausamer Code - schreibt man so wirklich c++?
Keine Ahnung 😳 Mann versucht so wie mann es gerade kann als Anfänger
Hat mit statischer Typisierung nur wenig zu tun, oder?
Ich dachte schon, mann könnte auch schreiben template<class T> Im Grunde versuch ich nur Hilfe zur Selbsthilfe bei meinem Problem zu finden,wie ich cin >> auch einen Pfad mitgeben kann ifstream istr(name.c_str()); Hier müsste irgendwie eine Pfad Angabe eingebaut werden.
Es ist nicht so kompliziert - es ist nur viel Arbeit, und ineffizient, wenn man weiß wo die 2 Dateien liegen.
Es ist schön das es für Dich nicht kompliziert ist, nur bringt es mir nicht viel da ich das wissen nicht habe, mir war am Anfang der Fragestellung nicht klar, das man wenn man nach dem Namen der Datei gefragt wird keinen Pfad zur Datei mitgeben kann. Auch bei diesem Programm es ist sehr gleich wie das erste nur Anstatt zu vergleichen erstellt es 1zu1Kopien, es funktioniert gut, nur würde ich gerne einen Pfad angeben können wo er zb ein kopiertes .jpg Bild ablegt. 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 | #include <iostream>
#include <vector>
#include <fstream>
using namespace std;
template<class T>
char* wie_bytes(T& i)
{
void* addr = &i;
return static_cast<char*>(addr);
}
int main()
{
cout << "Gebe den Namen der EingabeDatei ein\n";
string name;
cin >> name;
ifstream istr(name.c_str(),ios_base::binary);
if(!istr){cerr << "Fehler Datei existiert nicht!" << name << '\n';
return 1;}
cout << "Gebe den Namen der AusgabeDatei ein \n"
<< "VORSICHT bestehende Datei wird überschrieben" << '\n';
cin >> name;
ofstream schreib(name.c_str(),ios_base::binary);
if(!schreib){cerr << "Probleme beim Oeffnen der Ausgabedatei" << name << '\n';
return 2;}
vector<int>v;
int i;
while(istr.read(wie_bytes(i), sizeof(int)))
v.push_back(i);
for(int i=0; i<v.size(); ++i)
schreib.write(wie_bytes(v[i]), sizeof(int));
return 0;
}
|
|
Dakuan
Anmeldungsdatum: 2. November 2004
Beiträge: 6345
Wohnort: Hamburg
|
Mein Vorhaben ist ja anscheinend nicht umzusetzen, ...
Doch! Aber du solltest nicht so schnell aufgeben. Als Anfänger neigt man leicht dazu, zu viel auf einmal zu wollen, das kenne ich. Lass doch erstmal das Template weg und mache da eine einfache Funktion draus. Dann kommst du wahrscheinlich auch ohne oder mir weniger castings aus. Wenn du mit Verzeichnissen arbeiten willst, solltest du dir irgendwann (aber nicht jetzt) die Klasse <filesysten> (ab C++17) ansehen. Ich habe damit allerdings noch nicht gearbeitet, da meine Programme meist älter sind. Wenn die weißt wo deine Dateien liegen und du nicht immer den Pfad angeben willst, kannst du den Pfad ja auch erstmal im Programm fest kodieren.
| std::string start = "/home/<dein_username>/Verzeichnis/";
|
Dann kannst du den Pfad später zusammensetzen
Ich frage mich jetzt gerade wie die Suchfunktion von Nautilus das macht,der findet auch gesperrte Dateien.
Das ist ziemlich umfangreich und komplex, zumal da auch noch die Berechtigungen ermittelt werden müssen. Bei einigen Tooklits gibt es dafür aber bestimmt fertige Funktionen (habe ich jetzt aber nicht geprüft).
|
ChickenLipsRfun2eat
Anmeldungsdatum: 6. Dezember 2009
Beiträge: 12067
|
Dein Programm kann doch in verschiedenen Dateien vergleichen. Du musst lediglich den absoluten Pfad angeben. Also /home/ich/Desktop/Datei1 und /home/ich/Documents/Datei2. Was da natürlich nicht klappt ist die Expansion der bash, die bspw. ~ durch /home/ich ersetzt. Dafür gäbe es dann wie erwähnt schon argparse → das überlässt der Shell die Aufgabe die Pfade korrekt zu übergeben. Falls du viel mit Dateioperationen - die wirklich nicht trivial sind - machen möchtest, kann ich dir das Qt-Framework empfehlen. Das bietet für nahezu alles eine entsprechende Klasse oder mehrere.
|
ubuntu--anfaenger
(Themenstarter)
Anmeldungsdatum: 12. Oktober 2013
Beiträge: 1088
Wohnort: Belgien
|
Dakuan Doch! Aber du solltest nicht so schnell aufgeben. Als Anfänger neigt man leicht dazu, zu viel auf einmal zu wollen, das kenne ich.
Ja danke, und mit der Geduld ist das auch so eine Sache.Ich merke das ich schnell an meine Grenzen stosse.
Lass doch erstmal das Template weg und mache da eine einfache Funktion draus. Dann kommst du wahrscheinlich auch ohne oder mir weniger castings aus.
Dann werde ich das mal umschreiben, und das ohne template versuchen..mit getline Zeilenweise einlesen.
Wenn die weißt wo deine Dateien liegen und du nicht immer den Pfad angeben willst, kannst du den Pfad ja auch erstmal im Programm fest kodieren.
werde ich dann auch mal versuchen.
Das ist ziemlich umfangreich und komplex, zumal da auch noch die Berechtigungen ermittelt werden müssen.
Ja hab ich mir schon gedacht, wenn ich die ganze Platte mit Nautilus durchsuche,bekommt die cpu warm:) ChickenLipsRfun2eat Dafür gäbe es dann wie erwähnt schon argparse
Ich muss dann erstmal verstehen was parsen überhaupt ist, werde ich mal lesen. Leider hab ich diese Woche kaum Zeit um mich drum zu kümmern, ich melde mich sobald ich kann wieder. schonma vielen Dank.
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
ChickenLipsRfun2eat schrieb: Dein Programm kann doch in verschiedenen Dateien vergleichen. Du musst lediglich den absoluten Pfad angeben.
Das trifft es nicht. Relative Pfade funktionieren genauso: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 | # Ausgangslage:
t201:~/proj/mini/forum > cat aha oha
hallo
hallo
# Programm u. Daten im akt. Verzeichnis:
t201:~/proj/mini/forum > echo -e "aha\noha" | ./datvgl
Erste Datei:
Zweite Datei:
Dateien sind gleich!!!
# Aufruf aus dem Elternverzeichnis:
t201:~/proj/mini/forum > cd ..
t201:~/proj/mini > echo -e "forum/aha\nforum/oha" | forum/datvgl
Erste Datei:
Zweite Datei:
Dateien sind gleich!!!
# Vergleich von jwd:
t201:~/proj/mini > cd /tmp
t201:/tmp > echo -e "/home/stefan/proj/mini/forum/aha\n/home/stefan/proj/mini/forum/oha" | ~/proj/mini/forum/datvgl
Erste Datei:
Zweite Datei:
Dateien sind gleich!!!
|
Der Pfad muss eben - für Daten und Programm - stimmen. Man kann für das Programm auch den Shell-Shortcut ~ benutzen, für die Dateien nur $HOME, weil die Tilde nicht expandiert wird (ist etwas tricky, da durchzusehen, aber kein C++ - Phänomen). | t201:/tmp > echo -e "/home/stefan/proj/mini/forum/aha\n$HOME/proj/mini/forum/oha" | ~/proj/mini/forum/datvgl
Erste Datei:
Zweite Datei:
Dateien sind gleich!!!
t201:/tmp > echo -e "$HOME/proj/mini/forum/aha\n~/proj/mini/forum/oha" | ~/proj/mini/forum/datvgl
Erste Datei:
Zweite Datei:
Kann Datei 2 nicht lesen!!!
|
Eine Lösung, die im späteren Einsatz möglichst flexibel ist, ohne zu viel an Programmieraufwand zu erfordern, ist die Übergabe der Dateien, wie schon von anderen vorgeschlagen, per Shell, so dass Du es so aufrufen kannst: | ~/proj/mini/forum/datvgl aha ~/proj/mini/forum/oha
|
Autocomplete nachbauen ist aufwändig, Filesuche nachbauen ist aufwändig und schränkt die Nutzbarkeit womöglich stark ein. ubuntu--anfaenger Dann werde ich das mal umschreiben, und das ohne template versuchen..mit getline Zeilenweise einlesen.
Das mit dem Template betraf nur mein Verständnis, wie die Dateiinhalte verglichen werden - mit dem Finden oder Nichtfinden hat das gar nichts zu tun.
Ich frage mich jetzt gerade wie die Suchfunktion von Nautilus das macht,der findet auch gesperrte Dateien.
Meinst Du versteckte Dateien?
Es ist schön das es für Dich nicht kompliziert ist, nur bringt es mir nicht viel da ich das wissen nicht habe, mir war am Anfang der Fragestellung nicht klar, das man wenn man nach dem Namen der Datei gefragt wird keinen Pfad zur Datei mitgeben kann.
Auch bei diesem Programm es ist sehr gleich wie das erste nur Anstatt zu vergleichen erstellt es 1zu1Kopien, es funktioniert gut, nur würde ich gerne einen Pfad angeben können wo er zb ein kopiertes .jpg Bild ablegt.
Man kann doch den Pfad angeben - absolut oder auch relativ - man muss es nur machen und bei langen Pfaden ist das natürlich ermüdend, fehlerträchtig und aufwendig. Die leichteste Lösung die zugleich flexibe ist, ist es argc/argv zu benutzen. Obige Experimente habe ich alle mit Deinem unveränderten Programm (außer Einrückungen) gemacht. So sähe, mit minimalen Anpassungen, eine Lösung mit Argumenten aus (header etc. gleich geblieben): 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 | int main (int argc, char** argv)
{
if (argc == 3) {
ifstream istr (argv[1]);
if (!istr) {
cerr << "Kann Datei 1 nicht lesen!" << '\n';
return 1;
}
ifstream uistr (argv[2]);
if (!uistr) {
cerr << "Kann Datei 2 nicht lesen!" << '\n';
return 2;
}
vector <int> eins, zwei;
int i, t;
while (istr.read (wie_bytes (i), sizeof(int)))
eins.push_back(i);
while (uistr.read (wie_bytes (t), sizeof(int)))
zwei.push_back(t);
if (i==t) {
cout << "Dateien sind gleich." << endl;
}
else
cout << "Dateien ungleich." << endl;
}
else {
cout << "Zwei Dateien als argumente übergeben (Datei1, Datei2)\n";
return 3;
}
}
|
Der User kann auf der Kommandozeile Pfadvervollständigung nutzen, Dateien im aktuellen Verzeichnis ohne Pfad und relative Pfade.
|
Dakuan
Anmeldungsdatum: 2. November 2004
Beiträge: 6345
Wohnort: Hamburg
|
Ja danke, und mit der Geduld ist das auch so eine Sache.Ich merke das ich schnell an meine Grenzen stosse.
Das ist aber eine Hürde, die man nehmen muss. Bei meiner ersten abstrusen Idee hatte ich damals fast 4 Wochen gebraucht, um festzustellen, ob sie überhaupt umsetzbar ist. Nach 6 Monaten hatte ich dann etwas vorführbares.
Dann werde ich das mal umschreiben, und das ohne template versuchen..mit getline Zeilenweise einlesen.
Ich dachte da eigentlich eher an eine selbst gebaute Funktion. Aber ich habe mir deinen Code nochmal genauer angesehen (ist etwas verwirrend). Es geht wohl auch ganz ohne. Also wenn du nur willst, das ein gelesenes Byte aus einer Datei auf dem Speicherplatz von i landet, sollte es auch anders gehen. Allerdings hast du i als int deklariert, da ist dann wohl eine Typ Anpassung erforderlich.
while( istr.read( reinterpret_cast<int>(i), sizeof(char))
der zweite Parameter gibt die Anzahl der gelesenen Bytes an, nicht die Größe des Ziels. Wenn i ein char wäre sollte auch ein
while( istr.read( &i, sizeof(char) )
reichen, wenn ich jetzt nicht komplett daneben liege (C++ mache ich nur nebenbei). Die Konvertierung zu int sollte dann (automatisch?) beim push_back(i) erfolgen.
... wenn ich die ganze Platte mit Nautilus durchsuche,bekommt die cpu warm:)
Kenne ich. Wenn ich mit meinem eigenen Programm eine externe Platte mit ca. 400000 Dateien abarbeiten lasse, kocht die CPU nur deshalb nicht über, weil USB2 nicht schnell genug ist, und die CPU immer wieder mal warten muss. Dauer daher ca. 6 Minuten. p.s.: Das Problem mit den relativen Pfaden habe ich mir jetzt nicht genauer angesehen. Um das selber einzubauen müsste man die Funktion
getenv("HOME")
bemühen und etwas String Verarbeitung betreiben. Nachtrag - Lesestoff: std::istream::read
|
ubuntu--anfaenger
(Themenstarter)
Anmeldungsdatum: 12. Oktober 2013
Beiträge: 1088
Wohnort: Belgien
|
Hallo, Sorry das ich mich jetzt erst zurück melde, hatte viel an der Backe und wenig Zeit. user_unknown So sähe, mit minimalen Anpassungen, eine Lösung mit Argumenten aus (header etc. gleich geblieben):
Ja die ist toll deine Lösung..das reicht mir auch schon so.
Der User kann auf der Kommandozeile Pfadvervollständigung nutzen
Ja so gehts viel schneller autocomplete funktioniert! danke 👍 Dakuan Das ist aber eine Hürde, die man nehmen muss. Bei meiner ersten abstrusen Idee hatte ich damals fast 4 Wochen gebraucht, um festzustellen, ob sie überhaupt umsetzbar ist. Nach 6 Monaten hatte ich dann etwas vorführbares.
Ok dann bin ich beruhigt..
Ich dachte da eigentlich eher an eine selbst gebaute Funktion. Aber ich habe mir deinen Code nochmal genauer angesehen (ist etwas verwirrend). Es geht wohl auch ganz ohne.
Hm das mit der selbst gebauten Funktion, krieg ich nur auf die Reihe wenn ich den code aus meinem Eingangspost ändere, wegen der main(int argc, char** argv) bekomme ich das nicht in einer ausgelagerten Funktion rein. Das mit dem Template weglassen, habe ich aber wohl hinbekommen..so sieht der neue code jetzt aus 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 | #include <iostream>
#include <fstream>
using namespace std;
int main(int argc, char** argv)
{
if(argc==3){
ifstream istr(argv[1]);
if(!istr)
{cerr << "Fehler beim einlesen Datei1: " << '\n';
return 1;
}
string s;
getline(istr, s, '\0');
ifstream ustr(argv[2]);
if(!ustr)
{cerr << "Fehler beim einlesen Datei2: " << '\n';
return 2;
}
string t;
getline(ustr, t, '\0');
if(s==t){
cout << "Die Dateien sind gleich" << '\n';
}
else
cout << "Die Dateien sind ungleich" << '\n';
}
else{
cout << "Zwei Dateien als argumente übergeben (Datei1, Datei2)\n";
return 0;
}
}
|
Was wirklich noch schön wäre, wenn ich das Programm in eine Funktion auslagern könnte und main() dann nur noch die Funktion aufruft, da ich noch eine andere Funktion da reinbauen möchte mit einer Abfrage ob mann Dateien vergleichen will oder die andere Funktion benutzen will..
|
Dakuan
Anmeldungsdatum: 2. November 2004
Beiträge: 6345
Wohnort: Hamburg
|
Ich habe mir deine erste Version nochmal vorgenommen und etwas abgeändert.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 | #include <iostream>
#include <fstream>
using namespace std;
int vergleich( char a, char b ); // Prototyp
int main() {
string name1;
string name2;
char i;
char t;
int ergebnis;
cout << "Erste Datei: " << '\n';
cin >> name1;
ifstream istr(name1.c_str());
if(!istr){
cerr << "Kann Datei 1 nicht öffnen!!!" << '\n';
return 1;
}
cout << "Zweite Datei: " << '\n';
cin >> name2;
ifstream uistr(name2.c_str());
if(!uistr){
cerr << "Kann Datei 2 nicht öffnen!!!" << '\n';
return 2;
}
while( istr.good() && uistr.good() ) {
istr.read( &i, 1 );
uistr.read( &t, 1 );
ergebnis = i - t; // version 1
//ergebnis = vergleich( i, t ); // version 2
if( ergebnis != 0 )
break;
}
if( ergebnis == 0 )
cout << "Dateien sind gleich!!!" << endl;
else
cout << "Dateien ungleich" << endl;
return 0;
}
// Vergleichsfunktion
int vergleich( char a, char b ) {
return a - b;
}
|
Die read Funktion ließt Bytes ungeprüft und schreibt sie in einen Puffer. Der ist in diesem Fall nur 1 Byte lang (char). Es sind die Adressen der Variablen i und t. Wenn du den Vergleich von einer Funktion ausführen lassen möchtest musst du die Zeilen mit Version 1/2 tauschen. Ich habe da vorne noch einen Prototypen eingefügt. Den kann man weglassen, wenn man die Funktion dort platziert. Vielleicht hilft dir das ja. Eigentlich ist das noch ein als C++ verkleidetes C-Programm, aber mit irgendwas muss man ja mal anfangen.
|
ubuntu--anfaenger
(Themenstarter)
Anmeldungsdatum: 12. Oktober 2013
Beiträge: 1088
Wohnort: Belgien
|
Ja das funktioniert auch gut..aber ich würde trotzdem die vorrige Version nehmen da dort Pfadvervollständigung geht.. lg,
|