2016-04-08 71 views
0

海蘭大家, 我有這樣的代碼:重複文件指向同一位置

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

不要在ANSI FILE *中使用POSIX'dup()'。 – 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

我用'fpos_t position'變量使用'fgetpos()'和'fsetpos()'函數,但是我必須在'fsetpos()'之後放一個'fseek()',因爲'fgets()'把文件指針在下一行的開頭。 謝謝你的隊友! –

+0

@Federic Cuozzo另外我在你的問題中看到你可以讀寫文件。如果沒有調用移動遊標語句(如fseek();例如'fseek(f,SEEK_CUR,0);這個函數不應該工作,'將光標移動到當前位置(lol)就足夠了。 – jdarthenay