2016-04-08 3 views
0

Hy все, Я этот код:Дубликат указатель файла в том же положении

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"); 

и он будет работать на файл, например так:

<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> 

Основной указатель файла (FILE *fp) находится в main().

Моя идея заключается в том, чтобы дублировать указатель файла fp (который передается в прототипе), если я нахожу тег <item ...>, потому что, если этот тег связан с именем службы, что я хочу, чтобы стереть, я чтобы заменить всю строку <item ...>.

Но у меня проблема ... когда я буду выполнять snprintf() и fputs(), файл будет перезаписан в начале файла, потому что, imho, я думаю, что указатель файла не дублируется.

Есть ли способ или обходной путь для устранения/устранения этой проблемы?

Спасибо заранее!

+0

Что такое «дубликат»? Единственное, что мы видим в вашем коде, это 'fpTemp', который, по-видимому, является локальной переменной. Вы не называете 'fopen' нигде. Никто не может ответить на этот вопрос именно этим кодом. Также см. [Почему while (! Feof (fp)) всегда неверно] (http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong). – Lundin

+2

Не используйте POSIX 'dup()' с ANSI 'FILE *'. – jdarthenay

+0

@ Lundin Я отредактировал сообщение ... Я добавил 'fopen'. –

ответ

1

Вам не нужно дублировать указатель на файл, вам нужно использовать ftell()/fseek(). Небольшой код без обработки ошибок. (Поэтому, пожалуйста, не копируйте его, не добавляя обработку ошибок, проверяя возврат).

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 

Кроме того, кажется, что вы можете использовать fgetpos() и fsetpos().

+0

Я использовал функции 'fgetpos()' и 'fsetpos()' с переменной 'fpos_t position', но мне пришлось поставить' fseek() 'после' fsetpos() ', потому что' fgets() 'помещает указатель файла в начале следующей строки. Спасибо, товарищ! –

+0

@Federic Cuozzo Также я вижу в вашем вопросе вы альтернативно читаете и пишите в файл. Это не должно работать без вызова движущегося оператора курсора, такого как 'fseek();' например 'fseek (f, SEEK_CUR, 0);' для перемещения курсора в его текущее положение (lol) может быть достаточно. – jdarthenay

Смежные вопросы