Optimierungsbedarf
-
Moin. Habe mit C++ angefangen und mich soweit eingeübt.
Habe dieses programm zum Zerlegen von Dateien geschrieben#include <iostream> #include <fstream> #include <dir.h> using namespace std; int main(int argc, char *argv[]) { // benötigte variablen über jeder schleife deklarieren char path[200]; char *dir = "test"; char cur_part_path[100]; ifstream fin; ofstream fou; size_t limit; unsigned long write_pos; int filenr, filescreated; char tmp; while (true) { // nach zu zerlegenden datei fragen. fflush(stdin); cout << "Datei: "; cin.get(path, sizeof(path)); if (path == "exit") break; // zu zerlegende datei öffnen ifstream fin (path); if (!fin.is_open()) { cout << "Datei existiert nicht oder konnte nicht geöffnet werden!" << endl; continue; } // abfragen, wie viele bytes pro part. while (true) { cout << "Bytes pro Part: "; cin >> limit; if (limit != 0) break; cout << "0 Bytes? Das gäbe unendlich viele Parts." << endl; } if (mkdir(dir) == -1) { cout << "-> Konnte Verzeichnis für die Parts nicht erstellen." << endl; cout << " Wahrscheinlich existiert das Zielverzeichnis bereits!" << endl; } else { filescreated = 0; filenr = 1; while (!fin.eof()) { // pfad zum aktuellen part sprintf(cur_part_path, "%s%s%s%s%d", dir, "/", path, ".part", filenr); cout << cur_part_path << endl; write_pos = 0; while (fin.get(tmp)) { if (!fou.is_open()) { fou.open (cur_part_path); if (!fou.is_open()) { cout << "Konnte Part nicht anlegen und zum Schreiben öffnen." << endl; break; } filescreated++; } fou.put(tmp); if (++write_pos >= limit) break; } filenr++; // wurde für diesen durchlauf kein neuer part angelegt, ist der job erledigt if (!fou.is_open()) break; fou.close(); } fin.close(); // prozessverlauf ausgeben printf("-> %d Parts erstellt!\n", filescreated); } } cin.ignore(); return 0; }
Es wird gefragt, welche Datei zerlegt werden soll.
Ein Verzeichnis test wird relativ zur working directoty
angelegt, wo alle Stück-Dateien reinkommen.
Gibt es noch ein mögliches Risiko zu beachten oder
etwas für die Perormance zu verbessern?Bitte für einen Anfänger erklären.
Möchte auch weder mit string.h noch sstream.h arbeiten.
-
Sicherheitsrisiko 1: 'fflush(stdin)' erzeugt undefiniertes Verhalten. Verwende lieber cin.ignore(), um den Eingabepuffer zu leeren.
Sicherheitsrisiko 2: Die Größenüberprüfung von char-Arrays ist praktisch nicht existent. Das bedeutet, daß du relativ schnell über den Verfügbaren Speicherbereich hinausschreiben könntest (gerade der sprintf()-Aufruf sieht da gefährlich aus - du versuchst im Extremfall 215 Zeichen in ein 100-Zeichen-Array zu quetschen). Da bist du mit std::string auf der sicheren Seite.
Problem 3: Anstatt nur auf is_open() bzw. eof() zu überprüfen, solltest du die komplette Fehler-Palette abfangen (fail()).
Performance 4: Anstatt jedes Zeichen einzeln durch den Speicher zu jagen, kannst du auch größere Blöcke nehmen und kopieren.
-
Wie darf ich das verstehen, dass fflush() undefiniertes Verhalten hat?
Kann ich nciht auch nen char Pointer nehmen?
-
sjBlack schrieb:
Wie darf ich das verstehen, dass fflush() undefiniertes Verhalten hat?
Genau so: Das Verhalten von
fflush( )
auf Eingabestreams ist undefiniert!greetz, Swordfish
-
http://www.c-plusplus.net/forum/viewtopic-var-p-is-1146014.html
#include <cstdlib> #include <iostream> using namespace std; int main(int argc, char *argv[]) { char * test; char buffer[100]; while (true) { int c; while ((c = getchar())!=EOF && c!='\n'); cin.get(buffer, sizeof(buffer)); test = buffer; cout << test << endl; system("PAUSE"); } system("PAUSE"); return 0; }
Bekomme bei der ersten Eingabe nichts ausgegeben.
Bei den restlichen hingegen schon.
Woran liegt das?// nachtrag
Bekommt man hier keinen Support? Ist dieses Forum purer Wissensaustausch
unter Informatikern? Niemand anfängerfreundlich?// nachtrag 2
#include <cstdlib> #include <iostream> using namespace std; int main(int argc, char *argv[]) { char * test; char buffer[100]; int c; while (true) { cin.get(buffer, sizeof(buffer)); while ((c = getchar())!=EOF && c!='\n'); test = buffer; cout << test << endl; system("PAUSE"); } system("PAUSE"); return 0; }
Leere den Tastaturpuffer jetzt nach den Eingaben
und deklariere die int-variable außerhalb der
Schleife. Jetzt funktioniert es.
-
sjBlack schrieb:
http://www.c-plusplus.net/forum/viewtopic-var-p-is-1146014.html
#include <cstdlib> #include <iostream> using namespace std; int main(int argc, char *argv[]) { char * test; char buffer[100]; while (true) { int c; while ((c = getchar())!=EOF && c!='\n'); cin.get(buffer, sizeof(buffer)); test = buffer; cout << test << endl; system("PAUSE"); } system("PAUSE"); return 0; }
Bekomme bei der ersten Eingabe nichts ausgegeben.
Bei den restlichen hingegen schon.
Woran liegt das?Das liegt daran, daß vor der ersten Eingabe noch nichts im Puffer stand, was die while-Schleife entsorgen könnte.
// nachtrag
Bekommt man hier keinen Support? Ist dieses Forum purer Wissensaustausch
unter Informatikern? Niemand anfängerfreundlich?Klar bekommst du hier Unterstützung, aber schau mal auf die Uhr
PS: Klar kannst du char-Pointer verwenden, wenn du unbedingt Wert darauf legst. Aber dann mußt du ständig selber kontrollieren, ob du wirklich genug Platz für die unterzubringenden Daten hast (wenn du das vergisst: undefiniertes Verhalten).
PPS: Und "undefiniertes Verhalten" bedeutet, daß du nicht vorhersagen kannst, was das Programm macht - es kann sein, daß alles gut geht, aber es kann auch sein, daß du damit deine Festplatte in einen Klumpen Altmetall verwandelst.
-
aber es kann auch sein, daß du damit deine Festplatte in einen Klumpen Altmetall verwandelst.
Das ist zum Glück dann doch eher unwahrscheinlich
Grüße,
Martin
-
aber es kann auch sein, daß du damit deine Festplatte in einen Klumpen Altmetall verwandelst.
Das ist zum Glück dann doch eher unwahrscheinlich
Grüße,
Martin
-
JimmydaMage schrieb:
Das ist zum Glück dann doch eher unwahrscheinlich
Unwahrscheinlich vielleicht, aber technisch durchaus erlaubt.
(eigentlich wollte ich ja schreiben "daß du damit den vierten Weltkrieg auslöst" :D)