2016-04-08 12 views
0

Hy alle, Ich habe diesen Code:Duplicate File Zeiger an der gleichen Position

int lenInput; 
char input[64], buffer[512], temp[512], *ret, tagName[] = "<name>", tagItem[] = "<item "; 
bool deleted = false; 
FILE *fp, *fpTemp = NULL; 

if(! (fp = fopen(nameFile, "r+"))) { 
    perror("Error Opening File"); 
    exit(-1); 
} 

printf("Insert the Name of the service you want to erase... "); 
fgets(input, sizeof(input), stdin); 

lenInput = (int) strlen(input); 
input[lenInput-1] = '\0'; 
lenInput = (int) strlen(input); 

do { 
    fgets(buffer, sizeof(buffer), fp); 
    buffer[strlen(buffer)-1] = '\0'; 

    if((ret = strstr(buffer, tagName)) != NULL) { 
     if(strncmp(ret, tagName, strlen(tagName)) == 0) { 
      if((ret = strstr(ret, input)) != NULL) { 
       if(strncmp(ret, input, lenInput) == 0) { 
        snprintf(temp, sizeof(temp), "<item present=\"false\">\n"); 
        fputs(temp, fpTemp); 

        deleted = true; 
        } 
      } 
     } 
    } 
    else if((ret = strstr(buffer, tagItem)) != NULL) { 
     if(strncmp(ret, tagItem, strlen(tagItem)) == 0) { 
      fpTemp = fdopen(dup (fileno(fp)), "r+");  /* associates a stream with the existing file descriptor, fd */ 
     } 
    } 
} while((deleted != true) && (!(feof(fp)))); 

if(deleted == false) 
    printf("Error: Service Not Found!\n"); 
else 
    printf("Success: Service Erased!\n"); 

und es würde so an einer Datei arbeiten:

<serviceNumber>2</serviceNumber> 
<item present="true"> 
    <id>1</id> 
    <name>name1</name> 
    <description>descr1</description> 
    <x>1</x> 
    <y>1</y> 
</item> 
<item present="true"> 
    <id>2</id> 
    <name>name2</name> 
    <description>descr2</description> 
    <x>2</x> 
    <y>2</y> 
</item> 

Der Hauptdateizeiger (FILE *fp) ist in der main().

Meine Idee ist, den Dateizeiger fp (der im Prototyp übergeben wird) zu duplizieren, wenn ich das Tag <item ...> finde, weil, wenn dieses Tag mit dem Namen des Dienstes verknüpft ist, den ich löschen möchte, ich ' Um die gesamte <item ...> Zeichenfolge zu ersetzen.

Aber ich habe ein Problem ... wenn ich snprintf() und fputs() ausführen, wird die Datei am Anfang der Datei überschrieben, weil, ich denke, der Dateizeiger ist nicht doppelt gut.

Es gibt einen Weg oder eine Problemumgehung, um dieses Problem zu beheben/zu beheben?

Vielen Dank im Voraus!

+0

Was "duplizieren"? Das einzige, was wir in Ihrem Code sehen können, ist 'fpTemp', das offensichtlich eine lokale Variable ist. Du rufst 'fopen' nirgends an. Niemand kann die Frage nur mit diesem Code beantworten. Siehe auch [warum ist während (! Feof (fp)) immer falsch] (http://stackoverflow.com/questions/5431941/why-is-which-feof-file-always-wrong). – Lundin

+2

Verwenden Sie POSIX 'dup()' nicht mit der ANSI 'FILE *'. – jdarthenay

+0

@Lundin Ich habe den Beitrag bearbeitet ... Ich habe das 'fopen' hinzugefügt. –

Antwort

1

Sie müssen den Dateizeiger nicht duplizieren, Sie müssen ftell()/fseek() verwenden. Kleiner Code ohne Fehlerbehandlung. (Bitte kopieren Sie es nicht, ohne die Fehlerbehandlung hinzuzufügen, indem Sie die Rückgaben überprüfen).

FILE *f = fopen(f, "r"); 

// do various things with file 
long where_am_i = ftell(f); // if it fails, -1 is returned and errno is set to indicate the error. 

// Do stuff requiring moving cursor in f stream 

fseek(f, SEEK_SET, where_am_i); // same returns convention as ftell() 
// You moved cursor back, you can start reading again 

Auch scheint es, Sie fgetpos() und fsetpos() verwenden können.

+0

Ich habe 'fgetpos()' und 'fsetpos()' Funktionen mit 'fpos_t position' verwendet, aber ich musste ein' fseek() 'hinter' fsetpos() 'setzen, weil' fgets() 'das setzt Dateizeiger am Anfang der nächsten Zeile. Vielen Dank Kumpel! –

+0

@Federic Cuozzo Auch sehe ich in deiner Frage alternativ das Lesen und Schreiben in Datei. Dies soll nicht ohne einen Aufruf einer beweglichen Cursoranweisung wie 'fseek() funktionieren;' zum Beispiel 'fseek (f, SEEK_CUR, 0);' zum Bewegen des Cursors an seiner aktuellen Position (lol) kann ausreichen. – jdarthenay

Verwandte Themen