spooky Parameter
-
Hallo!
Erstmal eine Beschreibung was das Programm machen soll:
Öffnen einer Datei, entfernen von html code, speichern in eine Text-Datei.An sich funktioniert alles - nur ich möchte das man den Dateinamen der (HTML)-Datei als Parameter übergeben kann.
So enstand der Untenstehende Code.
Auf den ersten Blick funktioniert alles der Dateiname wird den so genannten String übergeben.
Doch auf einmal schreibt er nichts mehr in die Ausgabe *.txt.Drei Run-Möglichkeiten.
1. Exe Starten > Dateiname eingeben (da kein zusätzlicher Parameter übergeben wurde) >> Datei wird fehlerlos erstellt
2. Konsole öffnen > "...exe dateiname" > Dateinname wird richtig angezeigt >> Datei wird fehlerlos erstellt
3. Datei per Drag'n'Drop auf die Exe ziehn > Dateinname wird richtig angezeigt >> doch es wird garkeine Ausgabedatei erstellt (txt wird richtig eingelesen)#include <iostream> #include <fstream> #include <string> using namespace std; int i; char zeichen,text[1000000]; string dateiname; int htmlin(); // Oeffnet Datei und speichert den Inhalt in den char text int txtout(); // Entfernt HTML aus dem Inhalt und schreibt den Rest in Textdatei int main(int argc, char *argv[]) { i=argc-1; dateiname=argv[i]; cout<<"argc= "<<argc<<endl; cout<<"i= "<<i<<endl; cout<<"dateiname= "<<dateiname<<endl; if(i==0) { cout<<"Dateiname eingeben: "; cin>>dateiname; } htmlin(); txtout(); cout<<"Enter zum Beenden"<<endl; getchar(); }; int htmlin() { ifstream htmldatei; htmldatei.open(dateiname.c_str()); if ( ((bool)htmldatei)==false ) { cout<<"Datei wurde nicht gefunden"<<endl; getchar(); return 0; }; i=0; while(!htmldatei.eof()) { htmldatei.get(zeichen); text[i]=zeichen; i++; }; htmldatei.close(); return 0; }; int txtout() { ofstream txtdatei; txtdatei.open("html.txt"); if ( ((bool)txtdatei)==false ) { cout<<"html.text konnte nicht geöffnet werden"<<endl; getchar(); return 0; }; //Schreibe alles was nicht zwischen < > steht in die Datei for(i=0;i <= strlen(text);i++) { if(text[i] == '<') { while(text[i]!='>') i++; } else txtdatei<<text[i]; }; txtdatei.close(); return 0; };
-
Ein paar Tipps:
- Hinter die schließende Klammer einer if- oder while-Anweisung brauchst du kein Semikolon zu schreiben
- Du musst richtig einrücken! Vereinzelt machst du es ja, meistens aber nicht...
- Manche Sachen lassen sich bei dir durchaus zusammenfassen (Zeile 52 könnte so aussehen: "text[i++]=zeichen;"). Muss aber nicht, wenn das so für dich besser ist, dann lass es.
- text ist nur 1000000 Bytes groß. Falls du je eine größere Datei einlesen willst, bekommst du Probleme. Abhilfe schaffen könnte das dynamische Anfordern von Speicher (new/delete).
- Ich kann dir auf Anhieb nicht sagen, wo das Problem liegt, aber wenn du schrittweise mit dem Debugger durch das Programm gehst und die Werte deiner Variablen zur Laufzeit checkst, sollte sich der Fehler schnell finden lassen.
-
Beachtest du bei Drag&Drop auch das aktuelle Arbeitsverzeichnis?
-
@ _Matze danke für die Tipps ^^
Und noch einen größeren Dank an Fellhuhn ^^
Denn per Drag'n'Drop erstellt er die Datei in das Stadartverzeichniss
(bei XP meist C:\Dokumente und Einstellungen\user\)Ich bin davon ausgegangen das ers ins gleiche Verzeichnis wie die Datei erstellt ^^ (Da kann man lange den Fehler beim Prog suchen...)
(Was blöd ist dass ich erst ne Suche aufgesetz hab um zu schauen ob die Datei möglicherweise woanders gelandet ist --- die habe ich aber nach 5 seks abgebrochen weil ich dachte "neee")
---
Zu den "provisorischen" Einsatz des Speichers für den Text - ich werd mich mal an die dynamische variante machen.
Gibt es eigentlich eine Möglichkeit die Größe eine Datei im Voraus abzufragen (Speichergröße oder Zeichenanzahl)?
Da wäre die Umsetzung einfacher.MfG SITDnow
-
- du solltest grundsätzlich keine Variablen global machen, außer es geht garnicht anders.
- Funktionen kann man Parameter mitgeben und sie müssen nicht unbedingt Rückgabewert int haben: du benutzt globale char-Arrays wo du der Funktion besser Parameter übergenen könntest, und du deklarierst einen Rückgabetyp der keinen Sinn hat (weil immer 0) und den du nie benutzt.
- der Vergleich von boolschen variablen mit false in der if-abfrage ist unnötig, ein einfachesif (!xyz)reicht (oder sprechenderif (not xyz), wenn man nicht grade einen M$-Compiler benutzt)
- der Cast der Streams zu bool ist unnötig, die Konvertierung erfolgt problemlos automatisch:if (!textdatei)Ich tippe mal auf eine C-Vergangenheit bei dir. Denn obwohl du löblicherweise anders als andere auf sprintf und andere C-Funktionen verzichtest (mal abgesehn von strlen) lässt der Stil (früh definierte und globale variablen, parameterlose Funktionen die auf dies globals zugreifen etc.) darauf schließen. Hab ich recht?

-
pumuckl schrieb:
Ich tippe mal auf eine C-Vergangenheit bei dir. Denn obwohl du löblicherweise anders als andere auf sprintf und andere C-Funktionen verzichtest (mal abgesehn von strlen) lässt der Stil (früh definierte und globale variablen, parameterlose Funktionen die auf dies globals zugreifen etc.) darauf schließen. Hab ich recht?

Das könnte ja im Grunde jede prozedurale Sprache sein, oder? Damals in Clipper waren dicke Variablenlisten mit 30 oder 40 Globalen bei uns auch keine Seltenheit, das wurde mir sogar so beigebracht... genauso wie 1000 Zeilen große Funktionen usw...
-
pumuckl schrieb:
Ich tippe mal auf eine C-Vergangenheit bei dir. Denn obwohl du löblicherweise anders als andere auf sprintf und andere C-Funktionen verzichtest (mal abgesehn von strlen) lässt der Stil (früh definierte und globale variablen, parameterlose Funktionen die auf dies globals zugreifen etc.) darauf schließen. Hab ich recht?

Mal von matzes Einwand abgesehen, kenne ich diese Fragestellung sehr gut aus einer "verschobenen" Perspektive. Hier bei uns wird nämlich Kollegen, die C-Programme mit größeren Blöcken globaler Variablen und monolithischen Funktionen schreiben, oftmals eine COBOL-Vergangenheit unterstellt

-
Bei Ada müssen die Variablen sogar vor dem Funktionsrumpf deklariert werden.

tellg und seekg sind hilfreich beim Herausfinden der Größe der Datei (springen ans Ende mit seekg, Position mit tellg abfragen und wieder zurückspringen).
-
Fellhuhn schrieb:
Bei Ada müssen die Variablen sogar vor dem Funktionsrumpf deklariert werden.
Nö, müssen sie nicht.

-
Tachyon schrieb:
Fellhuhn schrieb:
Bei Ada müssen die Variablen sogar vor dem Funktionsrumpf deklariert werden.
Nö, müssen sie nicht.

Declare-Blöcke sind auch im Funktionsrumpf möglich, aber äußerst häßlich.
@Topic
Was den Pfad angeht, einfach einen Link auf die Exe legen und bei den Optionen des Links ein Arbeitsverzeichnis angeben. Oder aus argv[0] den Ordner der Exe auslesen.
-
Fellhuhn schrieb:
Tachyon schrieb:
Fellhuhn schrieb:
Bei Ada müssen die Variablen sogar vor dem Funktionsrumpf deklariert werden.
Nö, müssen sie nicht.

Declare-Blöcke sind auch im Funktionsrumpf möglich, aber äußerst häßlich.
Das ist nicht hässlich, und sollte sogar viel und häufig benutzt werden, da man so a) ein Exception-Handling mit deutlich besserer Granularität erreichen kann, und man b) die Lebenszeit von Auto-Variablen (C-Sprech) auf sinnvolle Scopes begrenzen kann.
-
Ich muss sagen das ich mein ganzes Wissen mir selbst aus iwelchen Tutorials angeeignet habe ^^
Und eig. waren die meist C++ Orientiert...Naja es wird sich schrittweise bessern da ich seit Oktober Angewandte Informatik Studiere (naja bis jetzt haben wir noch nicht sehr viel gemacht - abgesehen davon lernen wie im ersten Semester nur C (2. C++ und 3. Java)
Ein Defizit sind aber auf jeden Fall Übergabewerte, ich werde daran Arbeiten ^^
Nebenbei habe ich die Version 2.0 fertig > Bei der man mehrere Parameter auf einmal "reinziehen" kann - und nu wird auch das Ausgabeverzeichnis klar definiert und die Text-Ausgabedatei hat den gleichen Namen wie die Inputfile. Zudem sind nun Leerzeichen im Dateinamen/-pfad erlaubt.
Es funktioniert soweit alles Prima

Obwohl ich glaube wenn ich den Quellcode veröffentliche jagt man mich aus jeden Forum ^^ (nein kein goto aber sehr schlecht formatiert)
Ich werde mir mal eure Tipps zu Herzen nehmen und denn Quellcode ein wenig überarbeiten ^^
-
Hey, nichts gegen gotos. Hab hier ein 13 Jahre altes millionenschweres Projekt und finde da täglich welche drin. Das ist eine Heidenarbeit die wegzubekommen, macht fast Spaß...

-
Wir haben mehr oder weniger eingetrichtert bekommen NIEMALS - wirklich NIE gotos zu verwenden XD
Einer meiner Dozenten sagte mal:
Goto's sind Teufelszeug
(Ist ja auch recht verständlich warum)
...wirklich!: Niemals!
-
SITDnow schrieb:
Wir haben mehr oder weniger eingetrichtert bekommen NIEMALS - wirklich NIE gotos zu verwenden XD
In meiner Fachoberschule (Fachbereich Informationstechnik) hatten wir es auch eingetrichtert bekommen, nur um dann im Praktikum einen Lehrer zu haben dem scheinbar Schleifen fremd waren. Er hat alles - aber auch wirklich alles - mit goto gelöst. Bei seinen Aufgaben war ich immer einer der langsamsten, weil ich als einziger immer alles auf Schleifen umgestellt habe.
cu André