fopen counter
-
Hi,
meine C Kenntnisse sind leider sehr gering, ich programmiere eher PHP, musste aber nun eine lib für eine Software schreiben, welche als Modul beim Start der Software geladen wird.
Ich poste 2 Codeausschnitte, der erste liest die Zahl einer Datei ein, erhöht diese +1. im 2ten Codeausschnitt wird der erhöhte Wert zurückgeschrieben.
Es ist im grunde eine Zählfunktion, wie oft eine bestimmte Aktion ausgeführt wird.Lesen:
mutex_lock(); FILE *f_last_id_read; unsigned long last_id; if((f_last_id_read = fopen("/var/lib/ldap-notifier/last_transaction_id", "r")) == NULL) { mutex_unlock(); return; } char buf[sizeof(long)]; fread(buf, sizeof(long), 1, f_last_id_read); fclose(f_last_id_read); last_id = atoi(buf) + 1;
Schreiben:
// Write last_id: FILE *f_last_id_write; if ((f_last_id_write = fopen("/var/lib/ldap-notifier/last_transaction_id", "w")) == NULL) { Debug( LDAP_DEBUG_ANY, "auditlog translog(): Cannot write /var/lib/ldap-notifier/last_transaction_id!!!\n", 0, 0, 0 ); ldap_pvt_thread_mutex_unlock(&ad->ad_mutex); return; } fprintf(f_last_id_write, "%d", last_id); fclose(f_last_id_write); mutex_unlock();
Im Grunde interessiert mich, ob es bedenken bei diesem Code gibt?
Mir ist dabei nur eine Situation aufgefallen, der Counter ist bei einem Testlauf von 3 auf 39 gesprungen, ab 39 hat er normal weitergezählt..
Danke!
lG
-
fread
ist nicht das Gegenstück zufprintf
: http://www.cplusplus.com/reference/cstdio/fread/Mit
fread
werden Binärwerte eingelesen. Also so, wie der Computer das intern speichert.Wenn es menschenlesbar sein soll, dann
fscanf(last_id_read,"%d", &last_id); // lesen
fprintf(f_last_id_write, "%d", last_id); // schreiben
Wenn last_id ein
long
ist, ist %ld der richtige Formatspecifier.
Wenn last_id einunsigned long
ist, ist %lu der richtige Formatspecifier.Wenn es binär sein soll:
fread( &last_id, sizeof(last_id), 1, last_id_read); // lesen
fwrite(&last_id, sizeof(last_id), 1, f_last_id_write); // schreiben
Evtl. musst du das +1 nach dem lesen noch einbauen.
-
Nimm direkt
fscanf
:#include <stdio.h> #include <stdlib.h> int main(void) { FILE*f_last_id_read; unsigned long last_id; if(!(f_last_id_read=fopen("bla","r"))) { fclose(f_last_id_read); exit(EXIT_FAILURE); } if(!fscanf(f_last_id_read,"%lu",&last_id)) { fclose(f_last_id_read); exit(EXIT_FAILURE); } printf("ID: %lu\n",last_id); fclose(f_last_id_read); exit(EXIT_SUCCESS); }
Den Rest hat DirkB schon gesagt.
-
dachschaden schrieb:
if(!fscanf(f_last_id_read,"%lu",&last_id))
Ja, ja, die Fehlererkennung.
Im Erfolgsfall gibtfscanf
hier eine 1 zurück. Alles andere wäre ein Fehler.fscanf return Value schrieb:
If a reading error happens or the end-of-file is reached while reading, the proper indicator is set (feof or ferror). And, if either happens before any data could be successfully read, EOF is returned.
Wenn die Datei leer ist kommt ein EOF.
EOF ist nicht Null.Darum
if(1 != fscanf(f_last_id_read,"%lu",&last_id))
-
Ach geil, daran habe ich jetzt überhaupt nicht gedacht. Danke, DirkB.
-
Hi,
danke für eure Antworten!
ist es auch möglich, dass lesen & schreiben mit einem fopen durchzuführen?
habe schon einiges probiert mit rewind & co, aber er hängt die neue Zahl immer hinten dran..
lG
-
Das funktioniert, wenn der Modus ungleich append und für Lesen+Schreiben geeignet.
Zusätzlich muss beim Wechsel zw. Lesen+Schreiben Operationen noch ein explizites flush passieren.
-
DBGTMaster schrieb:
ist es auch möglich, dass lesen & schreiben mit einem fopen durchzuführen?
Mit "r+" als Mode geht das.
DBGTMaster schrieb:
habe schon einiges probiert mit rewind & co,
Musst du auch weiterhin nehmen
DBGTMaster schrieb:
aber er hängt die neue Zahl immer hinten dran..
Welchen Mode hattest du denn?
Du musst aber aufpassen. Es werden Bytes überschrieben, (keine Zeilen oder so). Die Datei wird dadurch nicht kürzer.
Du solltest entweder beimfprintf
ein \n oder Leerzeichen am Ende mit ausgeben oder/und eine Längenangabe beim Formatspecifier angeben.fprintf(f_last_id_write, "%10d\n", last_id); // schreiben
-
Oh danke, nun funktionierts doch!
lG