Problem mit binär Einlesen&Ausgeben
-
Hallo miteinander.
Ich beschäftige mich erst seit ein paar Wochen mit C++, von daher bitte "verständliche" Hilfen.
Zum Problem, der nachfolgende Code treibt mich bald in die Verzweiflung. Eigentlich soll es ein Experiment zu einer Verschlüsselung werden, aber nicht mal das blanke Einlesen und woanders Speichern funktioniert.
Es kompiliert, macht aber nichts.
Vielleicht offensichtliche Fehler, ich seh sie nicht. Hab mich größtenteils an Codebeispiele aus dem Inet gehalten.int main(int argc, char *argv[]){ if(argc>1){ char c; vector<char> vec; ifstream input (argv[1], ios::binary); while(!input.eof()){ input.get(c); vec.push_back(c); } input.close(); ofstream output ("./out.txt", ios::binary); for(int i=0; i<vec.size(); i++){ output << vec[i]; } output.close(); } return EXIT_SUCCESS; }
-
nEmai schrieb:
Hallo miteinander.
Ich beschäftige mich erst seit ein paar Wochen mit C++, von daher bitte "verständliche" Hilfen.
Zum Problem, der nachfolgende Code treibt mich bald in die Verzweiflung. Eigentlich soll es ein Experiment zu einer Verschlüsselung werden, aber nicht mal das blanke Einlesen und woanders Speichern funktioniert.
Es kompiliert, macht aber nichts.
Vielleicht offensichtliche Fehler, ich seh sie nicht. Hab mich größtenteils an Codebeispiele aus dem Inet gehalten.int main(int argc, char *argv[]){ if(argc>1){ char c; vector<char> vec; ifstream input (argv[1], ios::binary); while(!input.eof()){ input.get(c); vec.push_back(c); } input.close(); ofstream output ("out.txt", ios::binary); // mach hier mal so for(int i=0; i<vec.size(); i++){ output << vec[i]; } output.close(); } return EXIT_SUCCESS; }Keine Ahnung, ob das geht, aber ein Versuch ist es Wert ist gerade das offensichtlichste, was mir komisch vorkommt.
-
nEmai schrieb:
...
Es kompiliert, macht aber nichts.
...hast du das programm von der konsole aus gestartet und etwas eingegeben, damit auch was in argv[1] drin steht ?
da gehört eigentlich noch ein hinweis mit ins programm rein, das es eine eingabe erwartet, wenn nichts eingegeben wird

-
@drakon:
So hatte ichs zuerst, funktioniert auch nicht.@agga ugga
Das ist mir bekannt. Meine Aussage war vielleicht etwas unglücklich.
Es ist nicht vorgesehen etwas einzugeben, ich will das Teil starten indem ich eine Textdatei auf die kompilierte EXE ziehe. Dann ist der Pfad der gezogenen Datei, hab ich mir zumindest anzeigen lassen, in argv[1].
Es steigt ja überhaupt nur ein, wenn argc>1 ist.
-
könnte sein dass wenn du die datei so öffnest der file pointer am ende der datei ist und nicht am anfang und deswegen sofort eof zutrifft
probier mal bevor du anfängst zu lesen
input.seekg(0, ios_base::beg);
-
Dank den Tipps sieht mein Quelltext mittlerweile so aus, aber funktionieren tut er nicht wirklich. Es wird auch keine Datei out.txt erstellt.
#include <cstdlib> #include <iostream> #include <fstream> #include <vector> using namespace std; int main(int argc, char *argv[]){ if(argc>1){ //habe hier auch schon true probiert, aber auch ohne erfolg char c; vector<char> vec; ifstream input (argv[1], ios::binary); input.seekg(0, ios_base::beg); while(!input.eof()){ input.get(c); vec.push_back(c); } input.close(); ofstream output ("out.txt", ios::binary); for(int i=0; i<vec.size(); i++) output << vec[i]; output.close(); } return EXIT_SUCCESS; }
-
input.seekg(0, ios_base::beg) ist ueberfluessig, ifstream oeffnet ohne weitere Angaben die Datei immer so, dass die aktuelle Position am Anfang ist.
Ich habe dein Program 1:1 bei mir kompiliert und gestartet, und es macht genau das was es soll. Das wahrscheinlichste ist, dass du das Programm also einfach falsch aufrufst. Versuch es mal ueber die Kommandozeile zu starten.
Deine Einlese-Schleife liest uebrigens ein Zeichen zu viel ein. Denn eof() liefert erst dann true, wenn das "end of file" bereits gefunden wurde. Das letzte gelesene Zeichen musst du also verwerfen.
-
machs so:
#include <cstdlib> #include <iostream> #include <fstream> #include <vector> using namespace std; int main(int argc, char *argv[]){ if(argc>1){ cout << "kommandozeilenparameter gefunden" << endl; char c; vector<char> vec; ifstream input (argv[1], ios::binary); //input.seekg(0, ios_base::beg); while(!input.fail()){ // auch möglich: input.good(), letztes Zeichen muss trotzdem verforfen werden input.get(c); vec.push_back(c); } cout << "definieren des Vectors beendet" << endl; input.close(); cout << "Vector: "; for(int i=0; i<sizeof(vec); ++i) cout << vec[i]; cout << endl; ofstream output ("out.txt", ios::binary); for(int i=0; i<vec.size(); i++) output.write(reinterpret_cast<const char*>(&vec[i]), sizeof(vec)); // binär schreiben output.close(); cout << "schreiben beendet!" << endl; system("pause"); } else { cout << "keine Kommandozeilenparameter gefunden!" << endl; system("pause"); } return EXIT_SUCCESS; }immer die Arbeitsvorgänge anzeigen lassen, damit man weiß, wo der Fehler ist
(bei mir war "input.eof()" fehlerhaft)
-
Ich bedanke mich wiederum für die Hilfe.

Tatsächlich, wenn ich meine exe von der cmd mit dem Pfad als Argument starte geht es. Das fördert nun aber leider gerade nicht mein Verständnis, im Gegenteil.Ich habe meinen Code wieder etwas überarbeitet:
#include <cstdlib> #include <iostream> #include <fstream> #include <vector> using namespace std; int main(int argc, char *argv[]){ for(int i=0; i<sizeof(argv); i++){ cout << argv[i] << endl; } if(false){ //<---------!! cout << "Parameter gefunden!" << endl; char c; vector<char> vec; ifstream input (argv[1], ios::binary); while(!input.eof()){ input.get(c); vec.push_back(c); } cout << "Laden beendet!" << endl; input.close(); ofstream output ("out.txt", ios::binary); for(int i=0; i<vec.size(); i++) output.write(reinterpret_cast<const char*>(&vec[i]), sizeof(vec)); output.close(); cout << "Schreiben beendet!" << endl; } else{ cout << "keine Parameter gefunden!" << endl; } system("PAUSE"); return EXIT_SUCCESS; }Es bereitet mir nun 2 Probleme.
Das erste ist, wenn ich es ohne Argumente öffne hat es folgende Ausgabe:
I:\crypt\crypt.exe
Drücken sie eine beliebige Taste...Warum um alles in der Welt wird das cout im else übergangen, wenn ich schon direkt if(false) schreib??

Das zweite ist, wenn ich das 'false' wieder durch 'argc>1' ersetze macht es zumindest etwas, wenn ich es in der cmd folgendermaßen aufrufe:
I:\crypt\>crypt.exe txt.txtAusgabe:
crypt.exe
txt.txt
Drücken sie eine beliebige Taste..So weit so gut.**)
Kommen wir zur von mir bevorzugten Methode es zu öffnen. Drag&drop die Textdatei auf die exe und so starten. Es öffnet sich, Ausgabe:
I:\crypt\crypt.exe //<-argv[0]
I:\crypt\txt.txt //<-argv[1]
Drücken sie eine beliebige Taste...Und so funktioniert es nicht. Es Erstellt keine Ausgabedatei, nichts.
Mag mich das Programm nicht oder hat das n rationaleren Grund?Edit2: Mir ist geradet aufgefallen, dass alle couts übergangen werden, egal ob es funktioniert oder nicht. C++ ist mir zu hoch..

**)Wirklich zufrieden sein kann man mit dem, was dieser Code erzeugt auch nicht.
"Viel Spaß" im Eingang wird im Ausgang dazu:
VVi
Vie
Viel
Viel
Viel S
Viel Sp
Viel Spa
Viel Spaß
Viel Spaßß
Viel Spaßß Viel Spaßß iel Spaßß el Spaßß l Spaßß Spaßß Spaßß paßß aßß ßß ßMan erkennt zumindest, dass es wie in einem Schieberegister verschoben ist.

-
@double* T:
cout << "Vector: "; for(int i=0; i<sizeof(vec); ++i) cout << vec[i]; cout << endl;du bist dir sicher, dass das sooft durchläuft, wie du vermutest?

Nagut, analysieren wir mal deinen Quelltext:
Code 01
#include <cstdlib> #include <iostream> #include <fstream> #include <vector> using namespace std; int main(int argc, char *argv[]) { if(argc>1) { //habe hier auch schon true probiert, aber auch ohne erfolg char c; vector<char> vec; ifstream input (argv[1], ios::binary); input.seekg(0, ios_base::beg); while(!input.eof()){ input.get(c); vec.push_back(c); } input.close(); ofstream output ("out.txt", ios::binary); for(int i=0; i<vec.size(); i++) output << vec[i]; output.close(); } return EXIT_SUCCESS; }if(argc>1) { //habe hier auch schon true probiert, aber auch ohne erfolgDu willst einen Integer auf "true" testen? Das ist zwar möglich, aber definitiv falsch, wenn du dir die Definition von argc anguckst.
char c; vector<char> vec;Warum legst du die Variablen schon hier an? Wenn sich die Datei nicht öffnen lässt, kannst du dir das ganz sparen.
ifstream input (argv[1], ios::binary);Du öffnest die Datei binary? Ließt aber mit get ein? read/write wäre dann korrekt!
while(!input.eof()){ input.get(c); vec.push_back(c); }Aua. Das ließt definitiv ein Zeichen zu viel ein

while (input >> c) vec.push_back(c);sollte ausreichend sein.
input.close();macht der Destruktor von input automatisch!
ofstream output ("out.txt", ios::binary); for(int i=0; i<vec.size(); i++) output << vec[i]; output.close();(1) iteratoren sind hier wesentlich schneller
(2) du öffnest binary, streamst aber rein (statt write)
(3) close wird vom Destruktor von ouput automatisch aufgerufenCode 02
#include <cstdlib> #include <iostream> #include <fstream> #include <vector> using namespace std; int main(int argc, char *argv[]){ for(int i=0; i<sizeof(argv); i++){ cout << argv[i] << endl; } if(false){ //<---------!! cout << "Parameter gefunden!" << endl; char c; vector<char> vec; ifstream input (argv[1], ios::binary); while(!input.eof()){ input.get(c); vec.push_back(c); } cout << "Laden beendet!" << endl; input.close(); ofstream output ("out.txt", ios::binary); for(int i=0; i<vec.size(); i++) output.write(reinterpret_cast<const char*>(&vec[i]), sizeof(vec)); output.close(); cout << "Schreiben beendet!" << endl; } else{ cout << "keine Parameter gefunden!" << endl; } system("PAUSE"); return EXIT_SUCCESS; }S. Code 01!
for(int i=0; i<sizeof(argv); i++){ cout << argv[i] << endl; }Aua. Lass den Quatsch und nutz argc.
if(false){ //<---------!!Das wird definitiv NIE in erfüllung gehen -.-
=>
#include <iostream> #include <fstream> #include <vector> int main(int argc, char** argv) { if (argc != 2) /* argc == 1, wenn kein Parameter übergeben wurde. argv[0] == programmname */ { std::cerr << "FEHLER: Es wurden keine korrekten Parameter übergeben!\n" << argv[0] << " [-sourcefile]" << std::endl; return 1; } std::ifstream file_stream_source(argv[1]); if (!file_stream_source) // konnte Datei geöffnet werden? { std::cerr << "FEHLER: Datei(\"" << argv[1] << "\") konnte nicht geöffnet werden!" << std::endl; return 2; } std::vector<char> data; char temp_char; while (file_stream_source >> temp_char) data.push_back(temp_char); std::ofstream file_stream_destination("output.txt"); for (std::vector<char>::const_iterator it(data.begin()); it != data.end(); ++it) file_stream_destination << *it; }. So geht das, mit deinem Ansatz (jedes Zeichen einzellnt einlesen [in vector] und dann wieder ausgeben). Einfacher geht es per iteratoren:
#include <iostream> #include <fstream> #include <vector> #include <iterator> #include <algorithm> int main(int argc, char** argv) { if (argc != 2) /* argc == 1, wenn kein Parameter übergeben wurde. argv[0] == programmname */ { std::cerr << "FEHLER: Es wurden keine korrekten Parameter übergeben!\n" << argv[0] << " [-sourcefile]" << std::endl; return 1; } std::ifstream file_stream_source(argv[1]); if (!file_stream_source) // konnte Datei geöffnet werden? { std::cerr << "FEHLER: Datei(\"" << argv[1] << "\") konnte nicht geöffnet werden!" << std::endl; return 2; } std::vector<char> data(std::istream_iterator<char>(file_stream_source), std::istream_iterator<char>()); std::ofstream file_stream_destination("output.txt"); std::copy(data.begin(), data.end(), std::ostream_iterator<char>(file_stream_destination)); }Und noch einfacher ist es, direkt den Buffer zu kopieren

#include <iostream> #include <fstream> int main(int argc, char** argv) { if (argc != 2) /* argc == 1, wenn kein Parameter übergeben wurde. argv[0] == programmname */ { std::cerr << "FEHLER: Es wurden keine korrekten Parameter übergeben!\n" << argv[0] << " [-sourcefile]" << std::endl; return 1; } std::ifstream file_stream_source(argv[1]); if (!file_stream_source) // konnte Datei geöffnet werden? { std::cerr << "FEHLER: Datei(\"" << argv[1] << "\") konnte nicht geöffnet werden!" << std::endl; return 2; } std::ofstream file_stream_destination("output.txt"); file_stream_destination << file_stream_source.rdbuf(); }... sodele
