Komandozeilenparameter übergeben und Laufzeit messen



  • Hi,
    ich habe ein c++ Prog geschrieben was Fibonaccizahlen ausrechnet.
    Das sieht zur Zeit wie folgt aus:

    // dua_u3.1a.cpp: Hauptprojektdatei.
    
    #include <iostream>
    using namespace std;
    
    //Funktionsprototypen
    unsigned int fib(unsigned int);
    
    int main()
    {
    	unsigned int n;
    	cin >> n;
    	cout<<fib(n);
    	return 0;
    }
    //Funktionen
    unsigned int fib(unsigned int zahl)
    	{
    	if(zahl == 0)
    		return zahl;
    	if(zahl == 1)
    		return zahl;
    	return fib(zahl-1) + fib(zahl-2);
    	}
    

    Ich hab jetzt 2 Probleme.Das erste, ich will das n nicht eingelesen wird sondern per Komandozeilenparameter übergeben werden soll.
    Es soll dan wie folgt aussehen: "fibonacci n".
    Das zweite,ich würde gern die Laufzeit messen die es braucht um die Fiboncci-Folge zu berechnen.
    Bei den beiden Problemen weiß ich nicht wie ich diese Implementieren soll.
    Für Ratschläge wär ich dankbar.
    Gruß steve



  • du musst die signatur deiner main-fkt folgendermaßen abändern:
    int main(int argc, char* argv[])

    argc sagt dir, wie viele argumente übergeben wurden - wobei argv[0] immer die working-directory ist - also müsstest du gucken, ob argc == 2 ist. Wenn ja, dann guckst du, was in argv[1] steht...

    bb



  • An die Kommandozeilenargumente kommst du über die Parameter der main() -Funktion.

    Diese bestehen (wenn nicht void ) aus einem int , der die Anzahl Argumente angibt, und einem char** , der auf ein dynamisches Array von C-Strings ( char* ) zeigt. Die Parameter kannst du wie normale Funktionsparameter verwenden.

    Hier zum Beispiel eine einfache Applikation, die alle übergebenen Parameter der Reihe nach nummeriert auf der Konsole ausgibt:

    int main(int argc, char** argv)
    {
        for (int i = 0; i < argc; ++i)
        {
            std::cout << i << ": " << argv[i] << std::endl;
        }
    }
    


  • Ja ok, aber sagen wir ma ich nehme den wert der in argv[1] drin steht.
    Denn er müsste ja dann mein übergebener Parameter sein.
    Dann ist er doch immer noch ein wert vom typ Char oder?
    Ich brauch ja zur berechnung der fibonacci-zahlen int bzwm unsigned int....
    gruß steve



  • Nicht vom Typ char , sondern vom Typ char* , genauer ein C-String.

    Mittels std::stringstream kannst du umwandeln:

    int main(int argc, char** argv)
    {
        int Value;
        std::stringstream Stream;
        Stream << argv[1];        // Argument einlesen
        Stream >> Value;          // in int konvertieren und unter Variable Value speichern
    }
    

    Im Link steht noch mehr.



  • Geht irgendwie nicht hab es umgeschrieben aber der Compiler meckert.
    Er meckert über das "stringstream"......
    Das Programm sieht jett so aus:

    // dua_u3.1a.cpp: Hauptprojektdatei.
    #include <iostream>
    using namespace std;
    
    //Funktionsprototypen
    unsigned int fib(unsigned int);
    
    int main(int argc, char *argv[])
    {
    unsigned int n;
    
    	//wurden Parameter übergeben??
    	if(argc >= 1)
    		{
    		int value;
    		stringstream Stream;
    		Stream <<  argv[1];
    		Stream >> value;
    		n = value;
    		}
    	else
    		{
    		cin >> n;
    		}
    
    	cout<<fib(n);
    
    	return 0;
    }
    //Funktionen
    unsigned int fib(unsigned int zahl)
    	{
    	if(zahl == 0)
    		return zahl;
    	if(zahl == 1)
    		return zahl;
    	return fib(zahl-1) + fib(zahl-2);
    	}
    

    Jemand ne Idee?

    Gruß Steve



  • #include <ctime>
    #include <ofstream>
    #include <string>
    
    struct Zeitmesser
    {
    private:
      const std::clock_t start;
      const std::string ausgabe_datei_name;
    
    public:
      Zeitmesser(const std::string &_ausgabe_datei_name) : ausgabe_datei_name(_ausgabe_datei_name), start(std::clock()) {}
    
      ~Zeitmesser()
      {
        std::ofstream ausgabe_datei (ausgabe_datei_name.c_str());
        ausgabe_datei << std::clock() - start << std::endl;
      }
    
    int main(/*...*/)
    {
      Zeitmesser bla("hier_steht_dann_drin_wie_lang_es_gedauert_hat.txt");
      /*
      ganz normales programm
      */
    }
    

    Wenn man möchte, kann man für die erste Zeile auch noch nen Makro anlegen - so wird es zumindest meistens gemacht

    bb

    PS: guck mal auf der seite - da steht auch drin, wie die datei heißt, die du includen musst, um stringstream zu nutzen... jz besser? ^^



  • WINFO2105 schrieb:

    Geht irgendwie nicht hab es umgeschrieben aber der Compiler meckert.
    Er meckert über das "stringstream"......

    Bitte gib in Zukunft genauere Fehlermeldungen an. Und nein, er meckert nicht; sei froh, dass er diesen Fehler zur Komplierzeit erkennt. 🙂

    In meinem Link steht etwas über die grundsätzliche Anwendung von StringStreams. Ich wollte zuerst nur den Link posten, aber dann habe ich noch einen Code zum besseren Verständnis geschrieben. Damit du wenigstens noch etwas dabei lernst, musst du noch herausfinden, welchen Header du benötigst. 😉



  • Ach stimmt da muss ja noch ne Datein includen,wo ich stringstream nutzte... 🙄
    Will das dann auf der Konsole ausgeben aber das geht ja dann auch grob so.
    Was ist den das dann für ne einheit?Sekunden oder Millisekunden



  • kannst dir die klasse auch so umbauen, dass du ne referenz auf nen ofstream übergibst und dort eben std::cout übergeben, dann geht das auch ganz gut ^^

    wie du die sekunden rausbekommst sollte hier ersichtlich sein:
    http://www.cplusplus.com/reference/clibrary/ctime/clock/

    bb



  • So hab jetzt alles hinbekommen.
    Ich hab die übergebenen Parameter mit atoi() konvertiert und bei der Zeiterfasung hab ich die "time.h" includet und dann so mit den darin enthaltenen Befehlen die Laufzeit gemessen. 😃
    Hier werden die Fibonacci-Zahlen von n1 bis n2 berechnet und die Laufzeit zum Schluss ausgegeben.
    Vollstänigkeitshalber hier noch ma der fertige Code:

    #include <time.h>
    #include <iostream>
    
    using namespace std;
    
    //Funktionsprototypen
    unsigned int fib(unsigned int);
    
    int main(int argc, char *argv[])
    {
    unsigned int n1;
    unsigned int n2;
    double time = 0.0;
    double tstart;
    
    	if(argc > 1)
    		{
    		n1 = atoi(argv[1]);
    		n2 = atoi(argv[2]);
    		}
    	else
    		{
    		cin >> n1;
    		cin >> n2;
    		}
    
    	tstart = clock();
    for( int i = n1; i <= n2 ; i++)
    	{
    	cout<<fib(i)<<endl;
    	}
    
    	time += clock() - tstart;
    	time = time / CLOCKS_PER_SEC;
    
    	cout << "Laufzeit: " << time << " sekunden" << endl;
    
    	return 0;
    }
    //Funktionen
    unsigned int fib(unsigned int zahl)
    	{
    	if(zahl == 0)
    		return zahl;
    	if(zahl == 1)
    		return zahl;
    	return fib(zahl-1) + fib(zahl-2);
    	}
    

    Danek für die ganze Hilfe.
    MFG Steve



  • #include <time.h> //der header heißt <ctime>!
    #include <iostream>
    
    using namespace std;
    
    //Funktionsprototypen
    unsigned int fib(unsigned int); //hier mag es noch gehen, dass man beim prototypen die bezeichnung des parameters weglässt - solltest du dir aber sehr schnell abgewöhnen, weils einfach ma hässlich ist...
    
    int main(int argc, char *argv[])
    {
    	unsigned int n1;
    	unsigned int n2;
    
    	if(argc > 1) //na toll - wenn argc == 2 ist, ist die bedingung erfüllt und er will argv[2] lesen -> BÄM
    	{
    		n1 = atoi(argv[1]);
    		n2 = atoi(argv[2]);
    	}
    	else
    	{
    		cin >> n1;
    		cin >> n2;
    	}
    
    	const clock_t start = clock();
    	for( int i = n1; i <= n2 ; i++)
    	{
    		cout<<fib(i)<<endl;
    	}
    
    	const clock_t end = clock();
    	const float time = (end-start) / CLOCKS_PER_SEC;
    
    	cout << "Laufzeit: " << time << " sekunden" << endl;
    
    	return 0;
    }
    //Funktionen
    unsigned int fib(unsigned int zahl)
    {
    	if(zahl == 0)
    		return zahl;
    	if(zahl == 1)
    		return zahl;
    	return fib(zahl-1) + fib(zahl-2);
    }
    

    so siehts scho bissl schöner aus, oder?! 😛

    PS: Da du auf std::stringstream verzichtet hast, hast du jz nen Problem:
    atoi gibt dir nen int zurück... du willst aber nen unsigned int...

    eine alternative wäre http://www.cplusplus.com/reference/clibrary/cstdlib/atol/ und dann gucken, ob das ergebnis in nen unsigned int reinpasst und wenn, ja dann zuweisen, wenn nicht, exception werfen oder so...

    oder du gehst einfach über std::stringstream - würd ich dir auch empfehlen....


Log in to reply