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
-
freadist nicht das Gegenstück zufprintf: http://www.cplusplus.com/reference/cstdio/fread/Mit
freadwerden Binärwerte eingelesen. Also so, wie der Computer das intern speichert.Wenn es menschenlesbar sein soll, dann
fscanf(last_id_read,"%d", &last_id); // lesenfprintf(f_last_id_write, "%d", last_id); // schreibenWenn last_id ein
longist, ist %ld der richtige Formatspecifier.
Wenn last_id einunsigned longist, ist %lu der richtige Formatspecifier.Wenn es binär sein soll:
fread( &last_id, sizeof(last_id), 1, last_id_read); // lesenfwrite(&last_id, sizeof(last_id), 1, f_last_id_write); // schreibenEvtl. 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 gibtfscanfhier 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 beimfprintfein \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