Tachesacht, ich versuche gerade mir ein paar Werte zum debuggen auszugeben. Das Programm errechnet nen Haufen Werte erst fuer x=10 rechne, rechne ,rechne dann fuer x=20 , rechne ,rechne ,rechne fuer x = 30 usw. Jetzt haette ich gerne dass das Programm die Werte fuer x=10 in die erste Spalte schreibt, x=20 in die zweite Spalte usw. Momentan arbeite ich mit fprintf, schreibe die Werte fuer x=10 runter: fprintf(file, "%d", x10); wollte dann den Schreibpointer via: fseek(file, 0L, SEEK_SET); wieder an den Anfang setzen und dann via fprintf(file, "\t %d", x20); in die naechste Spalte schreiben. Dummerweise scheint er den fseekt Befehl vollkommen zu ignorieren. Das Ergebnis im file sieht quasi so aus: x10 x10 x10 x10 x10 x10 x10 x10 x20 x20 x20 x20 x20 x20 x20 x30 x30 x30 x30 x30 x30 jemand ne idee wie ich das in diese Form bekomme: x10 x20 x30 x10 x20 x30 x10 x20 x30 x10 x20 x30 x10 x20 x30 x10 x20 x30 Danke schonmal fuer die Hilfe!
vergiss das mit dem seek. ordne deine Berechnungen so, dass du gleich alle 3 Daten asugeben kannst, oder - sollte das nicht gehen - halte sie solange im Speicher, wie nötig. bei extrem großen Datenmengen schreibst du ebend 3 Files und generierst zum schluss das mehrspaltige
Mach's im Hauptspeicher so, wie Du es haben willst, und dann schreib es einfach in einem Rutsch in die Datei rein.
Icke_Wa schrieb: > Dummerweise scheint er den fseekt Befehl vollkommen zu ignorieren. Das wundert mich etwas. Kann es sein, dass das verwendete Filesystem keine Seeks unterstützt? Eigentlich hätte ich erwartet, dass nach dem fseek die bereits bestehenden Daten einfach überschrieben werden, wobei das natürlich auch nicht das ist, was man will. Hier ist eine korrigierte Version mit fseek, die zumindest hier unter Linux funktioniert:
1 | #include <stdio.h> |
2 | |
3 | #define ANZ_ZEILEN 10
|
4 | #define ANZ_SPALTEN 3
|
5 | #define SPALTENBREITE 4
|
6 | #define ANZ_ZEILENENDE 1 // 1 für Linux, 2 für DOS & Co
|
7 | |
8 | int main(void) { |
9 | FILE *fp = fopen("log", "w"); |
10 | long pos; |
11 | int s, z; |
12 | |
13 | for(s=0; s<ANZ_SPALTEN; s++) { |
14 | for(z=0; z<ANZ_ZEILEN; z++) { |
15 | pos = z*(ANZ_SPALTEN*SPALTENBREITE+ANZ_ZEILENENDE)+SPALTENBREITE*s; |
16 | fseek(fp, pos, SEEK_SET); |
17 | fprintf(fp, "%*d", SPALTENBREITE, s*z); |
18 | if(s==ANZ_SPALTEN-1) |
19 | fprintf(fp, "\n"); |
20 | }
|
21 | }
|
22 | fclose(fp); |
23 | return 0; |
24 | }
|
Ergebnis:
1 | 0 0 0 |
2 | 0 1 2 |
3 | 0 2 4 |
4 | 0 3 6 |
5 | 0 4 8 |
6 | 0 5 10 |
7 | 0 6 12 |
8 | 0 7 14 |
9 | 0 8 16 |
10 | 0 9 18 |
Hm ... also den Code so umaendern ... ja gehen tut das schon, aber ich wollte damit frueher oder spaeter auch Messwerte auslesen und sortieren um mir das ganze bloede Excell rumgeklicker zu spahren. @ Yalu. Das alles einfach ueberschrieben wird, war auch eigentlich meine Mindesterwartung, aber irgedwie mag der das wohl nich. Ich nutze hier Visual C++ auf Win. XP ... glaube mit diesem Standartcompiler, so von wegen System. Deine Code Yalu versteh ich noch nicht ganz. pos wird doch nach dem ersten durchlauf (s=0 und z=1) zu 13. Wo schreibt der denn mit pos=13 hin?
du solltest sich erstmal im klaren sein was eine Datei ist. Dort gibt es keine spalten. Dort gibt es auch keine Zeilen. Das ganze ist nur ein ansammlung von bytes. Man kann also nichts "einfügen" dann dafür muss man alles nach hinten schrieben. Yalu X. lässt also immer schon platz für die anderen Daten damit er sie später einfügen kann. Das ganze geht zwar ist aber extrem unflexibel. Schreibt die Daten einfach in eine Dantebank dann kannst du sie in jeden möglichen form auswerten.
Icke_Wa schrieb: > @ Yalu. Das alles einfach ueberschrieben wird, war auch eigentlich meine > Mindesterwartung, langsam. Ohne zusätzliches Gedöhns funktioniert das nicht so, wie du dir das vorstellst. Überschreiben heißt auch wirklich überschreiben. D.h. wenn du mit fseek zurück gehst an die Zeile, dann wird auch die Information am Anfang dieser Zeile überschrieben! Du kannst in einem Textfile nicht so einfach Zeilen verlängern (oder verkürzen). Dazu muss nämlich alles dahinterliegende im File entsprechend verschoben werden, was aber durch einfaches Überschreiben nicht passiert. d.h. du musst im File als allererstes dir Zeilen mit einer definierten Länge schaffen, die Leerzeichen enthalten, damit du in den späteren Durchgängen schon den Platz hast, an dem überschrieben werden kann. > Visual C++ auf Win. XP ... glaube mit diesem Standartcompiler, so von > wegen System. Der fseek funktioniert schon. Nur ist die ganze Herangehensweise für Textfiles nicht wirklich gut geeignet. Du musst dir ein Textfile wie eines von den alten Tonbändern vorstellen. Wenn du da Musik aufzeichnest und hinterher zwischen 2 Musikstücke ein drittes einfügen willst, dann reicht es nicht einfach das Tonband auf den Anfang des 2. Stückes zu setzen und dort dann das 3. aufzunehmen! Du überschreibst dir damit zwangsläufig das vorher dort gespeicherte 2. Stück. Wenn du nicht bei der ersten Aufnahme zwischen 1.tem und 2.tem Stück entsprechend Platz gelassen hast um dort dann das 3. Stück hinterher einsetzen zu können, hast du mit Zitronen gehandelt. Und genau das macht Yalu: er lässt sich entsprechend Platz und dreht das ganze so hin, dass er im "Text" an die entsprechende Position seekt, in der die x-te Spalte der y-ten Zeile beginnt. Beginnen muss, weil er weiß, wieviele Spalten es sind und wie breit jede Spalte ist (und am Zeilenende ein \n Zeichen steht) Und PS: Ein Tabulator, \t, ist ein Zeichen wie jedes andere. Dadurch, dass du einen \t aufs File schreibst, überspringst du nichts. Du schreibst ein \t Zeichen aufs File, mehr tust du damit nicht. Erst das Programm, welches die Daten anzeigt (bzw. dann der Display Treiber), wertet dem Tab eine spezielle Bedeutung zu und schickt den Cursor ein paar Zeichen nach rechts.
So ein Seek ist in Textdateien übrigens offiziell eigentlich gar nicht erlaubt.
Rolf Magnus schrieb: > So ein Seek ist in Textdateien übrigens offiziell eigentlich gar nicht > erlaubt. Diesen Paragraphen des BGB hat der Europäische Gerichtshof mittlerweile gekippt.
Das steht nicht im BGB, sondern in der ISO-Norm. Mit "offiziell nicht erlaubt" meinte ich eher, daß es bei den meisten Compilern wohl funktionieren dürfte, aber eigentlich gegen die ISO-Norm verstößt. Hier die entsprechende Passage daraus: "For a text stream, either offset shall be zero, or offset shall be a value returned by an earlier successful call to the ftell function on a stream associated with the same file and whence shall be SEEK_SET."
Rolf Magnus schrieb: > "For a text stream, either offset shall be zero, or offset shall be a > value returned by an earlier successful call to the ftell function on a > stream associated with the same file and whence shall be SEEK_SET." Ja, das habe ich auch gesehen, nachdem ich den obigen Beitrag abge- schickt hatte. Ich nehme an, diese Einschränkung wurde gemacht, um Verwirrung bei unterschiedlichen Zeilenend- und Zeichencodierungen zu vermeiden, glaube auf der anderen Seite aber nicht, dass sich die Lauf- zeitumgebung merkt, welche Offset schon einmal von ftell zurückgegeben worden sind und damit "legal" sind. Somit ist das obige Beispielprogramm zwar bäh, sollte aber trotzdem funktionieren (unter Linux mit GCC tat es das ja auch). Besser wäre es aber, die Datei im Binärmodus zu öffnen und die Behand- lung von Zeilenenden explizit auszuprogrammieren.
Mark Brandis schrieb: > Mach's im Hauptspeicher so, wie Du es haben willst, und dann schreib es > einfach in einem Rutsch in die Datei rein. Ich kann es noch ein paar mal wiederholen :-)
> unter Linux mit GCC tat es das ja auch
Unter Windows mit CRLF als Zeilentrenner funktioniert es natürlich
nicht.
Aber portabel schreiben fällt ja unter fortgeschrittenes Programmieren.
MaWin schrieb: >> unter Linux mit GCC tat es das ja auch > > Unter Windows mit CRLF als Zeilentrenner funktioniert es natürlich > nicht. Hast du's probiert (mit #define ANZ_ZEILENENDE 2)? Wenn es dich stört, dass das Makro an das jeweilige Betriebssystem angepasst werden muss, kannst du die Unterscheidung gerne mit "#ifdef WIN32" o.ä. automatisie- ren. Ich habe ja auch nichts gegen die Lösung, bei der die auszugebenden Daten erst einmal in einem großen Array zwischengespeichert werden. Aber zum einen ist das nur bis zu einer gewissen Datenmenge möglich bzw. sinnvoll, zum anderen wollte ich den Ansatz des TE, die Datei direkt zu beschreiben, zu Ende führen.
> #define ANZ_ZEILENENDE 1 // 1 für Linux, 2 für DOS & Co
Oh, super.
Ich hab halt gedacht, ab SPALTENBREITE Ziffern in der Zahle der ersten
Spalte wird die erste Ziffer überschrieben.
Yalu X. schrieb: > Ich habe ja auch nichts gegen die Lösung, bei der die auszugebenden > Daten erst einmal in einem großen Array zwischengespeichert werden. Aber > zum einen ist das nur bis zu einer gewissen Datenmenge möglich bzw. > sinnvoll, zum anderen wollte ich den Ansatz des TE, die Datei direkt zu > beschreiben, zu Ende führen. Ändert auch nix daran, dass der ganze Ansatz des TO nicht viel taugt. > aber ich wollte damit frueher oder spaeter auch Messwerte auslesen > und sortieren um mir das ganze bloede Excell rumgeklicker zu spahren. er wird die Daten sowieso in ein anderes Programm einlesen. Sinnlos da jetzt Klimmzüge zu machen um ein bestimmtes Datenformat hinzukriegen, dass dann eh keiner mehr braucht.
Yalu X. schrieb: > Ich habe ja auch nichts gegen die Lösung, bei der die auszugebenden > Daten erst einmal in einem großen Array zwischengespeichert werden. Aber > zum einen ist das nur bis zu einer gewissen Datenmenge möglich bzw. > sinnvoll, zum anderen wollte ich den Ansatz des TE, die Datei direkt zu > beschreiben, zu Ende führen. Wenn die Datenmenge tatsächlich richtig groß wird, sollte man wohl besser auf ein DBMS umsteigen, anstatt selbst händisch in Dateien herumzufuhrwerken. Da wird man doch nicht glücklich bei. Und mit SQLite macht es sogar auch bei nicht so großen Datenmengen schon Spaß ;-)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.