Fufialk Geschrieben 3. Februar 2006 Geschrieben 3. Februar 2006 Hallo, Ich habe mehrere kleine Programme geschrieben, die Messdaten auslesen und auswerten. Die Messdaten liegen als Dateien mit unterschiedlichen Dateiendungen vor (*.dat und *.msg). Ich möchte nun meine Vielen einzelnen Programme als Unterfunktionen eines einzigen Programmes zusammenfassen, um den Anwendern das Arbeiten zu erleichtern. Hierzu muss ich die per Drag & Drop übergebenen Dateien nach Ihren Endungen sortieren, wofür ich folgenden Code geschrieben habe: #include <iostream.h> // cin, cout #include <fstream.h> // ifstream, ofstream #include <stdlib.h> // exit, rand #include <iomanip.h> // setw #include <conio.h> // getch #include <sys/types.h> // off_t #include <sys/stat.h> // stat #include <time.h> // ctime, time #include <stdio.h> #include <string.h> //strcmp //void meldungen (); //void daten (); int main(int argc, const char* argv[]) { if (argc < 2) { printf("Starten Sie das Programm indem Sie die umzuwandelnden Daten"); printf("\nper Darg & Drop auf das Programmicon ziehen."); printf("\nBeenden mit Tastendruck."); getch(); exit(0); } int f; int nendung; for (f = 1; f < argc; f++) { cout << "\nFolgende Datei wird verarbeitet : " << argv[f]; char endung [3]; const char* find = strrchr(argv[f], '.'); //letztes "." finden strncpy(endung,find+1, 3); //3 Zeichen ab "." kopieren und "filewrite zuweisen cout << "\nEndung : " << endung; if ( strcmp ( endung , "dat" ) == 0 ) nendung = 0; else if ( strcmp ( endung , "msg" ) ==0 ) nendung = 1; else nendung = 2; switch (nendung) { case 0 : cout << "\nDatendatei"; break; case 1 : cout << "\nMeldungsdatei"; break; case 2 : cout << "\nEs handelt sich nicht um ein Messfile!"; break; } } getch(); } [/PHP] Mein Problem ist, daß nach der Dateiendung noch Leer bzw. Sonderzeichen an [b]char[/b] endung übergeben werden, obwohl hier nur 3 Zeichen stehen sollten. Zitieren
Klotzkopp Geschrieben 3. Februar 2006 Geschrieben 3. Februar 2006 Du solltest dich entscheiden, ob du die C-Dateifunktionen (printf) oder die C++-Streams (cout) benutzt. Mischen ist nicht so gut. Außerdem benutzt du veraltete C++-Headerdateien. #include <iostream> // cin, cout #include <fstream> // ifstream, ofstream #include <cstdlib> // exit, rand #include <iomanip> // setw #include <conio.h> // getch #include <sys/types.h> // off_t #include <sys/stat.h> // stat #include <ctime> // ctime, time //#include <cstdio> // NICHT MISCHEN #include <cstring> //strcmp [/code] So müsste das aussehen, wenn du nicht gerade einen sehr alten Compiler benutzt. Jetzt aber zum eigentlichen Problem: Du hast nur drei Zeichen für die Dateierweiterung. Da passt kein Nullzeichen mehr rein, wenn die Erweiterung selbst schon drei Zeichen hat. Ohne Nullterminierung werden die Daten, die im Speicher hinter deinem Array stehen, als Bestandteil des Strings interpretiert. Das kommt daher, dass strncpy keine Nullterminierung anhängt, wenn der Quellstring mehr Zeichen hat, als maximal kopiert werden sollen. Darum musst du dich also selbst kümmern, wenn du strncpy benutzt. Du solltest auch bedenken, dass Dateierweiterungen auch mehr als drei Zeichen haben können, ".jpeg" und ".html" zum Beispiel. Dein Programm wird außerdem wohl abstürzen, wenn du eine Datei ohne Erweiterung darauf ablegst. Was passiert, wenn du eine Datei benutzt, die selbst keine Erweiterung hat, die aber in ihrem Verzeichnispfad einen Punkt hat, will ich mir grad nicht ausmalen Ich frage mich allerdings, warum du dich überhaupt so mit char-Array abplagst. Warum nicht std::string? Zitieren
Fufialk Geschrieben 3. Februar 2006 Autor Geschrieben 3. Februar 2006 Das mit den veralteten Schreibweisen liegt sicherlich an der Lieteratur, die ich verwende, und auch daran, daß ich immer nur so weit an dem Programm arbeite, bis es das macht, was ich will. Sicherlich keine sehr gute Einstellung, ich kann mir aber leider nicht viel mehr Zeit nehmen. Die Sache mit den Arrays ist für mich sehr einfach zu verstehen, bsonders, da es hierzu auch sehr viel Dokumentation gibt. Während ich mit Funktionen wie std::string noch gar nicht gearbeitet habe. Was mir nicht ganz einleuchtet ist: Ich deklariere char endung [3] es dürften doch also gar nicht mehr als drei Zeichen dort stehen. Außerdem sage ich: strncpy(endung,find+1, 3); es sollen nur 3 Zeichen kopiert werden. Mit strlen kann ich die Länge meines Strins auslesen. Gibt es auch einen Befehl, um sie festzulegen? Zitieren
Klotzkopp Geschrieben 3. Februar 2006 Geschrieben 3. Februar 2006 Ich deklariere char endung [3] es dürften doch also gar nicht mehr als drei Zeichen dort stehen.Es stehen auch nicht mehr drin. Aber die String- und Ausgabefunktionen wissen nichts von Arrays. Die Größeninformation geht sowieso verloren, wenn man Arrays an Funktionen übergibt. Für strcmp oder den operator<< ist das nur ein Zeiger auf das erste Element deines Arrays. Um zu ermitteln, wie lang der String ist, müssen diese Funktionen die Nullterminierung suchen. Nach drei Zeichen ist zwar dein Array zuende, aber da ist immer noch keine Nullterminierung. Darum wird in dem dahinterliegenden Speicher weitergesucht, solange, bis entweder durch Zufall ein Nullbyte im Speicher steht, oder das ganze mit einer Zugriffsverletzung abstürzt. Mit strlen kann ich die Länge meines Strins auslesen. Gibt es auch einen Befehl, um sie festzulegen?Ja, setz eine Nullterminierung. Wie gesagt, strncpy macht das nicht automatisch für dich. Zitieren
Fufialk Geschrieben 3. Februar 2006 Autor Geschrieben 3. Februar 2006 Ja, setz eine Nullterminierung. Wie gesagt, strncpy macht das nicht automatisch für dich. Hab jetzt die Suche erfolglos strapaziert. Jedoch keinen Weg gefunden, mein Array bzw. den String zu Terminieren. Zitieren
Klotzkopp Geschrieben 3. Februar 2006 Geschrieben 3. Februar 2006 Du musst einfach nur an die Stelle hinter dem letzten Zeichen ein Nullzeichen ('\0') setzen. Oder einfach auf strncpy verzichten. Das ist sowieso nicht besonders sinnvoll. Oder noch besser: Gleich std::string benutzen. Dann brauchst du dir über solche Dinge überhaupt keine Sorgen zu machen. Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.