int main(...)



  • Hallo Leute, habe folgenden Auszug aus einem Quelltext:

    int main(int argc, char **argv)
    {
        // map und string initialisieren ...
        if(argc != 3)
           throw runtime_error("..");
    }
    

    Nun ist es ja so, das argc die Anzahl der strings unter argv angibt. Nur ist meine Frage woher weis mein Programm wie viel Argumente es hat??
    Der oben gezeigte Ausschnitt ist aus dem C++ Primer und wird in einem Programm verwendet, welches Wörter umwandeln soll. Es heißt argv[0] ist der Name des Programmes, argv[1] + [2] sollen die Namen der jeweiligen Dateien sein, also die Wortliste zum umwandeln und die Liste mit den Umwandlungswörtern. Nur kapier ich nicht, woher weis mein Programm das es jetzt auch 3 Argumente hat? Also woher weis es das es da noch 2 weitere Dateien gibt??

    -GhostfaceChilla-



  • Na von argc. Oder versteh ich die Frage falsch und du willst eigentlich wissen, wie das unter der Haube aussieht? Das hängt vom OS ab, es funktioniert beispielsweise unter Windos völlig anders als unter Unix.


  • Mod

    Die main ist auch nur eine Funktion*. Die wird vom Betriebssystem (oder genauer gesagt dem Startupcode) aufgerufen. Und dieser übergibt als erstes Argument die Anzahl der Zeichenketten, die er als zweites Argument übergibt. Da er selber die Zeichenketten übergibt, weiß er natürlich auch, wie viele das sind.

    *: bis auf ein paar Sonderregeln, wie dass man main nicht selber aufrufen darf und dass ein fehlendes return einem return 0 entspricht.



  • SeppJ schrieb:

    wie dass man main nicht selber aufrufen darf*

    *außer aus der main selbst

    Nur ist meine Frage woher weis mein Programm wie viel Argumente es hat??

    Das ist jetzt irgendwie blöd... ich kann die Antwort nicht richtig formulieren 😃 Sagen wir es mal so: Wenn die main ihre Parameter bekommt, dann wird doch der, der die Parameter "übergeben" hat, wohl wissen, wie groß das char-array-array ist`?



  • Ok, shconmal danke 🙂
    Also heißt es sozusagen das während das Programm gestartet wird, wird auch überprüft wie viel argumente es hat??
    Also der Quelltext ist der folgende:

    ifstream& open_file(ifstream&, const string&);
    
    int main(int argc, char **argv)
    {
        // map to hold the word transformation pairs: 
        // key is the word to look for in the input; value is word to use in the output
        map<string, string> trans_map;
        string key, value;
    
        if (argc != 3)
            throw runtime_error("wrong number of arguments");
    
        // open transformation file and check that open succeeded
        ifstream map_file;
        if (!open_file(map_file, argv[1]))
            throw runtime_error("no transformation file");
        // read the transformation map and build the map 
        while (map_file >> key >> value) 
            trans_map.insert(make_pair(key, value));
    {
        // ok: let's display it
        map<string, string>::iterator map_it = trans_map.begin();
    
        //cout << "Here is our transformation map: \n\n";
        while (map_it != trans_map.end()) {
            cout << "key: "   << map_it->first; 
            if (map_it->first.size() == 1)
                cout << "       ";
            if (map_it->first.size() == 3)
                cout << "     ";
            else if (map_it->first.size() == 4)
                cout << "    ";
            else if (map_it->first.size() == 5)
                cout << "   ";
            cout << "value: " << map_it->second << endl;
            ++map_it;
        }
        cout << "\n\n";
    
        {  // this block just produces the vector so that we can print it
           // for the book
        cout << "Here is our original string input:\n\n";
        // read some text to transform
        ifstream input;
        if (!open_file(input, argv[2]))
            throw runtime_error("no input file");
        string word;
        while (getline(input, word)) 
             cout << word << endl;
        cout << "\n\n\n";
        input.close(); input.clear();
        }
    }
    
        // ok, now we're ready to do the transformations
        // open the input file and check that the open succeeded
        ifstream input;
        if (!open_file(input, argv[2]))
            throw runtime_error("no input file");
    
        string line;   // hold each line from the input
    
        // read the text to transform it a line at a time
        while (getline(input, line)) {
            istringstream stream(line);  // read the line a word at a time
            string word;
            bool firstword = true;  // controls whether a space is printed 
            while (stream >> word) {
               // ok: the actual mapwork, this part is the heart of the program
               map<string, string>::const_iterator map_it =
                                   trans_map.find(word);
    
               // if this word is in the transformation map
               if (map_it != trans_map.end()) 
                   // replace it by the transformation value in the map
                   word = map_it->second;  
               if (firstword)
                   firstword = false;
               else
                   cout << " ";  // print space between words
               cout << word;
            }
            cout << endl;        // done with this line of input
        }
        return 0;
    }
    

    Also wo wird hier dem Programm die verschiedenen Argumente übergeben?Oder woher weis das Programm jetzt, das es neben dem Programmnamen noch 2 weiter strings in argv gibt??

    -GhostfaceChilla-



  • Hacker schrieb:

    SeppJ schrieb:

    wie dass man main nicht selber aufrufen darf*

    *außer aus der main selbst

    Das ist stumpf nicht wahr.

    ISO/IEC 14882:2003 3.6.1 (3) schrieb:

    The function main shall not be used (3.2) within a program.

    Für einen Ausruf aus main selbst wird keine Ausnahme gemacht.



  • Hä? Weil das Betriebssystem doch schon vor dem übergeben von argv weiß, auf wieviele aufeinanderfolgende Zeichenketten der Zeiger zeigt? Da wird ganix überprüft...


  • Mod

    Hacker schrieb:

    SeppJ schrieb:

    wie dass man main nicht selber aufrufen darf*

    *außer aus der main selbst

    Nein.

    King James Bible, 3.6.2,3 schrieb:

    Thou shalt not use the function main within a program.



  • Was vor Programmstart passiert, ist höchst systemabhängig. Ganz grob umrissen läuft das etwa so, dass die Shell (etwa bash oder cmd.exe) die Kommandozeile zerlegt, einen Kindprozess startet und die zerlegte Kommandozeile in execvp bzw. einen entsprechenden Syscall wirft, der das Betriebssystem dazu veranlasst, das Programm mit entsprechenden Parametern auszuführen.



  • Ok, aber wo wird hier dem Programm die verschiedenen Argumente übergeben?Oder woher weis das Programm jetzt, das es neben dem Programmnamen noch 2 weiter strings in argv gibt, also die 2 benötigten Daten?? Die müssen ja i-wie als Argumente übergeben werden....

    -GhostfaceChilla-



  • GhostfaceChilla schrieb:

    Ok, aber wo wird hier dem Programm die verschiedenen Argumente übergeben?Oder woher weis das Programm jetzt, das es neben dem Programmnamen noch 2 weiter strings in argv gibt, also die 2 benötigten Daten?? Die müssen ja i-wie als Argumente übergeben werden....

    Indem du sie dem Programm übergibst, so wie du anderen Programmen auch Parameter übergibst. (Tip: per Doppelklick auf die *.exe unter Windows wird das nichts. Versuch mal die Konsole...)



  • Vielleicht stell ich mir das zu einfach vor.

    Auf der Kommandozeile werden mehrere Strings an das Programm übergeben.
    Einmal der Programmname und, wenn vorhanden, weitere Argumente.
    argc wird dann entsprechend im Programm hochgezählt.

    In deinem Fall:
    argc = 0 --> String( Programmname )
    argc = 1 --> 1. Argument kann ein Dateiname sein oder ein Schalter, der das unter argc = 0 gestartete Programm beeinflusst.
    argc = 2 --> 2. Argument kann ein weiterer Dateiname sein oder ein Schalter.

    Sollten noch weitere Argumente übergeben werden, dann geht es so weiter.

    Von deinem Quelltext hängt es ab wie die Argumente behandelt werden.

    Wenn ihr den Quelltext entsprechend schreibt, könnte ihr einen Dateinamen auch unter Windows als 1.Argument übergeben. Nur mit weiteren fällt mir gerade kein direkter Weg ein, es sei denn man geht über Batch oder Scripte 👍



  • f.-th. schrieb:

    Nur mit weiteren fällt mir gerade kein direkter Weg ein, es sei denn man geht über Batch oder Scripte 👍

    Jop. Wenn du immer die gleichen Argumente übergibst, kannst du noch mit shortcuts arbeiten. Shortcut auf deine Exe erstellen, Eigenschaften anzeigen und dann die Argumente hinzufügen.



  • Besteht die klitzekleine Möglichkeit, dass du den Quelltext im INet gesucht und gefunden hast und jetzt nicht weißt, wie du das Programm aufrufen musst, damit es funktioniert? 😃



  • DocShoe schrieb:

    Besteht die klitzekleine Möglichkeit, dass du den Quelltext im INet gesucht und gefunden hast und jetzt nicht weißt, wie du das Programm aufrufen musst, damit es funktioniert? 😃

    Theoretisch schon, praktisch:

    Der oben gezeigte Ausschnitt ist aus dem C++ Primer



  • GhostfaceChilla schrieb:

    Hallo Leute, habe folgenden Auszug aus einem Quelltext:

    int main(int argc, char **argv)
    {
        // map und string initialisieren ...
        if(argc != 3)
           throw runtime_error("..");
    }
    

    Nun ist es ja so, das argc die Anzahl der strings unter argv angibt. Nur ist meine Frage woher weis mein Programm wie viel Argumente es hat??
    Der oben gezeigte Ausschnitt ist aus dem C++ Primer und wird in einem Programm verwendet, welches Wörter umwandeln soll.

    In welchem Buch genau steht das bitte? Voller Titel und Autor?
    Finde ich nämlich komisch, da ja nirgends ein try/catch in Sicht ist, wodurch im Falle argc!=3 das Programm undefiniertes Verhalten hervorruft. Das kann nicht wirklich ein positives Beispiel sein ...

    GhostfaceChilla schrieb:

    Es heißt argv[0] ist der Name des Programmes, argv[1] + [2] sollen die Namen der jeweiligen Dateien sein, also die Wortliste zum umwandeln und die Liste mit den Umwandlungswörtern. Nur kapier ich nicht, woher weis mein Programm das es jetzt auch 3 Argumente hat? Also woher weis es das es da noch 2 weitere Dateien gibt??

    Die Frage ist so einfach, dass ich bezweifle, sie richtig verstanden zu haben. Du willst doch jetzt sicherlich nicht hören, dass argc-1 die Zahl der Parameter ist, die das Programm bekommen hat, oder?

    In der Konsole:

    C:\DIGNS>meinprogramm.exe parameter1 "dies ist der zweite parameter"
    

    main wird dann mit
    `argc -> 3

    argv[0] -> "meinprogramm.exe"

    argv[1] -> "parameter1"

    argv[2] -> "dies ist der zweite parameter"

    `
    aufgerufen.


  • Mod

    krümelkacker schrieb:

    GhostfaceChilla schrieb:

    Hallo Leute, habe folgenden Auszug aus einem Quelltext:

    int main(int argc, char **argv)
    {
        // map und string initialisieren ...
        if(argc != 3)
           throw runtime_error("..");
    }
    

    Nun ist es ja so, das argc die Anzahl der strings unter argv angibt. Nur ist meine Frage woher weis mein Programm wie viel Argumente es hat??
    Der oben gezeigte Ausschnitt ist aus dem C++ Primer und wird in einem Programm verwendet, welches Wörter umwandeln soll.

    In welchem Buch genau steht das bitte? Voller Titel und Autor?
    Finde ich nämlich komisch, da ja nirgends ein try/catch in Sicht ist, wodurch im Falle argc!=3 das Programm undefiniertes Verhalten hervorruft. Das kann nicht wirklich ein positives Beispiel sein ...

    Das exakte Verhalten ist hier* nicht undefiniert, sondern implementation defined. Und zwar in engen Maßstäben: Die Implementierung kann wählen, ob sie den Stack aufräumt oder nicht, aber sie darf dir nicht Affen aus dem Arsch fliegen lassen. Danach wird garantiert std::terminate aufgerufen. Da beide Varianten akzeptabel sind, finde ich es völlig ok, das so zu handhaben.

    *: Also wenn kein catch gefunden wird. Ich nehme mal an, darauf beziehst du dich.



  • Hat sich erledigt habs herausgfeunden.
    Trotzdem Danke 🙂

    -GhostfaceChilla-


Anmelden zum Antworten