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 FunktionFilenamefür diesen Zweck. Letztendlich soll die Funktion dann in der Formf_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; }//mainWenn ich den Code compiliere (g++) und ausführe, erhalte ich als Ausgabe
~/code/C++ $ ./test
q084g090.csv
q100g075.csv
q090g100.csvWarum 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 byteWarum 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
-
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
-
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.