Dateinamen aus Schleifenvariable generieren



  • Ich möchte in einem C-Programm in einer Schleife Dateinamen nach dem Schema (z.B.) q100g035.csv generieren. Dieser Beispieldateiname soll generiert werden, wenn die (float) Variable q den Wert 1 hat und g den Wert 0.35 hat. q und g haben immer nur 2 Nachkommastellen.
    Ich verwende die Funktion Filename für diesen Zweck. Letztendlich soll die Funktion dann in der Form f_ptr = fopen (Filename(q,g).c_str(),"r"); verwendet werden.

    #include <iostream>
    #include <fstream>
    
    using namespace std; //endl
    using std::cout;
    
    void  IntToString(int i, char* buffer)
    {
    	sprintf(buffer, "%d", i);
    }
    
    std::string Filename(double q, double g)
    {
    	std::string f1,f3, f5, filename;
    
    	if (q==1) {f1="q";} else {f1="q0";}
    	char lala1[1]; //wenn ich das weglasse, gibt es Fehler.
    	char f2[3];
    	IntToString(100*q,f2);
    
    	if (g==1) {f3="g";} else {f3="g0";}
    	char lala2[1]; //wenn ich das weglasse, gibt es Fehler.
    	char  f4[3];
    	IntToString(100*g,f4);
    
    	f5=".csv";
    	filename=(f1+f2+f3+f4+f5);
    	return filename;
    }
    
    int main() {
    	cout << Filename(0.85,0.9) << endl;
    	cout << Filename(1,0.75) << endl;
    	cout << Filename(0.9,1) << endl;
    }//main
    

    Wenn ich den Code compiliere (g++) und ausführe, erhalte ich als Ausgabe

    ~/code/C++ $ ./test
    q084g090.csv
    q100g075.csv
    q090g100.csv

    Warum steht da 084 anstatt 085? Was mache ich falsch? Vermutlich ist die Funktion sowieso viel zu kompliziert und das geht alles einfacher. Aber wie?

    Gruß, Max



  • Hallo,

    char lala1[1]; //wenn ich das weglasse, gibt es Fehler.

    Weil Du da:

    char f2[3];

    den Platz für das 0-Byte vergessen hast.

    char f2[4];  // 3 Ziffern + null byte
    

    Warum steht da 084 anstatt 085

    Das sind Rundungsfehler weil doubles nicht mit dem Deszimalsystem sondern mit den Dualsystem arbeiten. Schreibe also statt:

    IntToString(100*q,f2);

    IntToString(100.0*q+0.5,f2);
    

    mfg Martin


  • Mod

    Machst du C oder C++? In C++ kannst du das wesentlich einfacher machen:

    #include <iostream>
    #include <string>
    #include <sstream>
    #include <iomanip>
    #include <cassert>
    
    using namespace std; 
    
    string Filename(double q, double g)
    {
      assert(q>0);   // Da ich nicht weiß, was du bei negativen Zahlen machen willst
      assert(g>0);   // mache ich hier mal provisorisch ein assert hin
    
      stringstream filename;
      filename<<'q'
              << setw(3)<< setfill('0') << int(q*100+0.5) // Simples runden positiver Zahlen
              <<'g'
              << setw(3)<< setfill('0') << int(g*100+0.5)
              <<".csv"; 
    
      return filename.str();
    }
    
    int main() {
        cout << Filename(0.85,0.9) << endl;
        cout << Filename(1,0.75) << endl;
        cout << Filename(0.9,1) << endl;
    }
    


  • xammm schrieb:

    Vermutlich ist die Funktion sowieso viel zu kompliziert und das geht alles einfacher. Aber wie?

    Gruß, Max

    Stimmt einfacher wäre z.B. sowas:

    char filename[16];
    sprintf( filename, "q%03dg%03d.csv", (int)(q*100.0+0,5), (int)(g*100.0+0,5) );
    

    mfg Martin


  • Mod

    mgaeckler schrieb:

    char filename[16];
    sprintf( filename, "q%03dg%03d.csv", (int)(q*100.0+0,5), (int)(g*100.0+0,5) );
    

    Manchmal bin ich von der schlichten Eleganz von C fasziniert. Ich ziehe die Bemerkungzurück, dass die C++-Lösung einfacher wäre. Wobei man aber noch darauf hinweisen sollte, dass der Threadersteller ziemlich wahrscheinlich doch C++ macht. Zum Glück kann er dort ja auch die C-Lösung verwenden.



  • Danke an euch alle. Ich hab die Lösung von Martin eben implementiert und es funktioniert super. Muss noch viel lernen...

    Grüße, Max



  • evtl. könnte man die buffer größe an sowas wie FILENAME_MAX binden 😕

    @edit es gibt auch noch andere makros



  • Dieser Thread wurde von Moderator/in rüdiger aus dem Forum ANSI C in das Forum C++ verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.


Anmelden zum Antworten