Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 20 von 27

Thema: Problem mit Namensräumen in C++

  1. #1

    Problem mit Namensräumen in C++

    Ich möchte in einem Programm mit Textdateien arbeiten, allerdings soll der Name der Textdatei vom Benutzer als Argument an das Programm übergeben werden.
    Codeschnipsel:
    Code:
    #include <fstream.h>
    
    main(int argc, char* argv[]){
    	if(argc == 2){
    		ifstream in(argv[1]);
    	}
    Mit der if-Abfrage will ich abfangen, dass versucht wird, eine Datei zu öffnen, die nicht als Argument übergeben worden ist.
    Das Problem: Wenn ich später auf die Variable in (also die Datei) zugreifen will, meckert der Compiler, dass die Variable nicht deklariert worden ist (außerdem wirft er eine Warnung, dass "in" nie benutzt wird).
    Die Frage: Wie kann ich das ganze so hinbekommen, dass ich später im Programm auf "in" zugreifen kann?

    Ich denke, dass ein paar von euch das wissen. Danke schonmal im Vorraus.

  2. #2
    Code:
     
    
    #include <iostream>
    ...
    using namespace std;
    
    main(int argc, char* argv[])
    {
        if(argc!=2) {return 0;}
        else
        {
             fsream file;
             file.open(argv[2], ios::out);                //out zum lesen, in zun schreiben
             if(file.is_open())
             {
                  //was immer du machen willst 
                  file.close(); 
             }
        }
        return 0;
    }
    habe den code nicht getestet, sollte allerdings funzen.

  3. #3
    Ich erlaub mir mal ein paar fehler zu berichtigen.
    fstream war nicht drin. argv[1] muss benutzt werden, nicht 2. und es war ein tippfehler bei fsream ohne t. ^^. ist aber immernoch ungetestet.
    außerdem kann man das else{} weglassen, da ja eh return-t wird, sollte argc nicht 2 sein. return = abbruch.
    Code:
     
    
    #include <iostream>
    #include <fstream>
    ...
    using namespace std;
    
    main(int argc, char* argv[])
    {
        if(argc!=2) {return 0;}
    
        fstream file;
        file.open(argv[1], ios::out);                //out zum lesen, in zun schreiben
        if(file.is_open())
        {
             //was immer du machen willst 
             file.close(); 
        }
        return 0;
    }

  4. #4
    fstream muss nicht included werden, ist in iostream beinhaltet

    das mit argv[2] war schändlich falsch von mir.

  5. #5
    Okay, jetzt geht's. Danke.

    Edit:
    Neues Problem, aber ich will nicht zu viele Threads öffnen.
    Wie kann ich eine ganze Zeile von cin auslesen, auch wenn Leerzeichen drin sind? Also dass meinetwegen die Eingabe
    Zitat Zitat
    hallo 123 test
    als eine Eingabe gewertet wird und das folgender (als Beispiel ausgedachter) Codeschnipsel die Ausgabe
    Zitat Zitat
    hallo 123 test
    und nicht
    Zitat Zitat
    hallo
    123
    test
    erzeugt?
    Code:
    string str;
    while(1){
    	cin >> str;
    	cout << str;
    }

    Geändert von Lukas (23.11.2004 um 20:11 Uhr)

  6. #6
    afaik geht das mit cin.getline(char*,streamsize,char);
    Erster Parameter ist dein String, 2. die Größe, und 3. Parameter ist das Zeichen wo er aufhören soll zu lesen. Es ist afaik '\n' beim 3. Parameter als Default-Wert eingestellt.

  7. #7
    Okay, das geht. thx

  8. #8
    Zitat Zitat von Cornuto/Dingsi
    Code:
        if(argc!=2) {return 0;}
    Das würde ich so auf keinen Fall machen, das ist schlechter Stil. Rückgabewerte wurden nicht dafür eingebaut, daß sie immer gleich sind!
    Code:
        if(argc!=2) {return 1;}
    So ist es besser; wenn man das Programm beendet, bevor es seine Arbeit getan hat, dann sollte man auch einen Rückgabewert != 0 zurückgeben.

  9. #9
    die rüchgabewerte werden hauptsächlich verwendet wenn in der shell gescriptet wird, weil keine eigentliche debug möglichkeit besteht. ist in einer ide wohl kaum der fall

  10. #10
    Nächste Frage:
    Ich habe eine Variable vom Typ string. Mit
    Code:
    atoi(str.c_str());
    (str ist mein String) kann ich ihn in eine int umwandeln. Das Problem ist, dass atoi() 0 zurückgibt, wenn der string nicht konvertierbar ist (sprich keine Zahl enthält). Allerdings möchte ich für mein Programm davon unterscheiden, ob die Zahl im String 0 ist oder ob der String keine Zahl ist. Also in etwa (Pseudo-Code):
    Code:
    if string_contains_int{
    	return int_im_string
    } else{
    	return irgendwas_bestimmtes_ungleich_null/false
    }

  11. #11
    Zitat Zitat von cornuto
    die rüchgabewerte werden hauptsächlich verwendet wenn in der shell gescriptet wird, weil keine eigentliche debug möglichkeit besteht. ist in einer ide wohl kaum der fall
    Das ist so eine Sache wie XHTML statt HTML - es geht auch problemlos ohne, aber die momentan als am korrektesten angesehene Variante ist eben mit. Zumal sich aus fallspezifischen Rückgabewerten keinerlei Nachteile ergeben, das Programm sich aber eher so verhält, wie man es als User erwarten würde - was eine Gute Sache ist.

    In der Unix-Welt sind Dinge wie mein_programm && etwas_anderes* weit verbreitet und ungemein nützlich; damit so etwas funktioniert müssen die Programme aber auch sagen können, ob sie korrekt beendet wurden.
    Argumente wie "ich benutze Windows und da macht man sowas nicht" sehe ich nicht als Begründung dafür an, sich einen schlechten Stil anzugewöhnen - wenn man später mal an einem Programm schreibt kann es gut angehen, daß es auf einer Plattform mit einer starken Shell läuft und saubere Rückgabewerte erwartet werden. Dann ist es gut, wenn man schon von Haus aus darauf achtet, fehlerspezifisch mit != 0 zu terminieren.


    * Sprich: mein_programm wird ausgeführt; wenn die Ausführung erfolgreich war wird etwas_anderes ausgeführt.

  12. #12
    C++ ist keine Skript-sprache. das waren wohl eher c zeiten

  13. #13
    der int return typ ist sowieso ein übrigbleibsel aus der c sprache, heute ist ebenso der void return typ für die main gebräuchlich

  14. #14
    Ich glaube, laut ANSI-Standard muss das 'ne int sein. Ich kann mich aber auch irren *zumfastallwissendenJeezschiel*

  15. #15
    Zitat Zitat von cornuto
    C++ ist keine Skript-sprache. das waren wohl eher c zeiten
    C ist genauso wenig eine Skriptsprache.
    Zitat Zitat von vivalaleche
    der int return typ ist sowieso ein übrigbleibsel aus der c sprache, heute ist ebenso der void return typ für die main gebräuchlich
    Nein. int ist und bleibt Standard. Alles andere ist MS-C-Mist.

  16. #16
    Zitat Zitat von masterquest
    Nächste Frage:
    Ich habe eine Variable vom Typ string. Mit
    Code:
    atoi(str.c_str());
    (str ist mein String) kann ich ihn in eine int umwandeln. Das Problem ist, dass atoi() 0 zurückgibt, wenn der string nicht konvertierbar ist (sprich keine Zahl enthält). Allerdings möchte ich für mein Programm davon unterscheiden, ob die Zahl im String 0 ist oder ob der String keine Zahl ist. Also in etwa (Pseudo-Code):
    Code:
    if string_contains_int{
    	return int_im_string
    } else{
    	return irgendwas_bestimmtes_ungleich_null/false
    }
    So, die Diskussion um den return wäre damit beendet. Ist mein Zitat Hinweis genug, was ich gerne wissen würde?

  17. #17
    Zitat Zitat von Dingsi
    Nein. int ist und bleibt Standard. Alles andere ist MS-C-Mist.
    Exakt. Man sollte unter keinen Umständen Microsotfs Methoden mit dem Standard verwechseln.


    Zum Thema "Skriptsprache": Das mit den Rückgabewerten hat durchaus seinen Sinn. Nehmen wir mal folgendes Grundproblem: Ich habe einen Haufen Rechner, in denen eine Festplatte durch ein neueres Modell ausgetauscht und die Daten gelöscht werden sollen, nachdem sie archiviert wurden.
    Kein Problem; ich erstelle mir ein Skript, das zuerst den Inhalt der alten Festplatte in ein Archiv auf der neuen Platte schreibt. Anschließend wird der Inhalt der alten Festplatte gelöscht.
    Der Haken: Das Skript muß wissen, ob das Archiv auch korrekt erstellt wurde. Wenn es einen Fehler nicht erkennt und einfach beim nächsten Schritt weitermacht kann ruck zuck der Inhalt einer Festplatte verschwinden.
    Mit Rückgabewerten ist das kein Problem: Ich überprüfe einfach den Rückgabewert jedes aufgerufenen Programms und breche ab, wenn er ungleich 0 ist. Wenn ich eine mächtige Shell wie bash benutze geht das sogar in einer Zeile:
    tar -cjf /mnt/platte2/archiv.tar /mnt/platte1/* && rm -rf /mnt/platte1/*
    Wenn tar einen Fehler hat wird rm gar nicht erst ausgeführt, was für die Daten sehr gesund ist.

    Ohne Rückgabewerte müßte ich nach dem Erstellen jedes Archiv einmal durchgehen und nachsehen, ob auch alle Dateien drin sind, die reinsollen. Unter Umständen ließe sich der Vorgang mit Standardmitteln nicht automatisieren, was für einen relativ einfachen computergestützten Algorithmus absolut lächerlich ist.


    Die C-artige Skriptsprache wäre übrigens Ch.


    @masterquest: Da dummerweise nicht mal atof in der Lage ist, für einen nichtnumerischen String NaN zurückzugeben, mußt du wohl irgendeinen Workaround finden... Zum Beispiel kannst du den String Zeichen für Zeichen durch isdigit() jagen. isdigit() findest du in ctype.h.

    Geändert von Jesus_666 (24.11.2004 um 20:58 Uhr)

  18. #18
    beruecksichtigt isdigit(char) eigentlich auch "." und "E" und "e" und "-" ?

    und selbst wenn, wuerde er nicht erkennen, dass "..." oder "1eee" keine Zahl ist.

    selbst wenn man die exponentendarstellung (1000 = 1E3) ausschliesst, hat man immer noch das problem des Typeoverflow .... der string kann ja schliesslich nahezu unendlich lang sein, der 32-bit Int ist ja schliesslich begrenzt ....

    Geändert von Ineluki (24.11.2004 um 22:27 Uhr)

  19. #19
    Zitat Zitat von Ineluki
    beruecksichtigt isdigit(char) eigentlich auch "." und "E" und "e" und "-" ?

    und selbst wenn, wuerde er nicht erkennen, dass "..." oder "1eee" keine Zahl ist.

    selbst wenn man die exponentendarstellung (1000 = 1E3) ausschliesst, hat man immer noch das problem des Typeoverflow .... der string kann ja schliesslich nahezu unendlich lang sein, der 32-bit Int ist ja schliesslich begrenzt ....
    In dem Fall würde ich sagen, daß man um die Konstruktion eines eigenen Parsers nicht herumkommt. Da C++ es nicht erlaubt, daß eine Integerfunktion etwas anderes als Ganzzahlen zurückgibt, kann man mit einer Funktion nicht arbeiten - vielleicht mit einer Prozedur.
    Sprich: Du übergibst drei Referenzen (auf den zu überprüfenden String, auf einen Integer und auf einen Boolean); die Prozedur liest dann den String aus und schreibt die erkannte Zahl in den Integer; falls der String keine Zahl enhtält wird der Boolean auf TRUE gesetzt und der Integer leergelassen. Das dürfte die einfachste Methode sein, in C++ einen String in einen Integer umzuwandeln und dabei Nichtzahlen als solche zu kennzechnen.
    Ist C++ nicht was Schönes?

  20. #20
    besser als ein true/false zurueck zu geben waere es, das ganze so zu handhaben, wie in der pascal-funktion val ...

    int val(char* s, int &value, int &errpos)=errpos;
    wobei in errpos die position des ersten fehlerhaften zeichens zurueck gegeben wird.

    willst du pascal konform sein, so waere errpos==0 kein fehler und erpos==1 wuerde bedeuten, dass das erste zeichen, also s[0] den fehler enthielte

    in c waere es aber wegen der 0-indexierung auch moeglich, -1 fuer fehlerfrei anzugeben, und ansonsten den index ,...

    wobei man bei der pascalnorm auch einfache ifs der form if(val("d23",zahl,err)) errorhandling; machen koennte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •