2016-04-08 7 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()にあります。

私の考えでは、このタグは私が消去したいと思い、そのサービスの名前にリンクされている場合、I」は、ので、私はタグ<item ...>を見つけた場合(プロトタイプで渡された)ファイルポインタfpを複製することです<item ...>文字列全体を置き換えてください。

しかし、私はsnprintf()fputs()を実行すると、ファイルの先頭にファイルが上書きされます。なぜなら、私はファイルポインタが重複していないと思うからです。

この問題を解決する方法や回避策がありますか?

ありがとうございます!

+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

私は 'fpospos()'と 'fsetpos()'関数を 'fpos_t position'変数で使っていましたが、' fset() 'の後に' fseekファイルポインタを次の行の先頭に挿入します。 ありがとうございました! –

+0

@Federic Cuozzoまた、私はあなたの質問であなたが別の方法でファイルを読み書きするのを見る。 '' fseek(f、SEEK_CUR、0);のように、現在の位置(lol)でカーソルを動かすためには、 'fseek();'のような移動カーソル文を呼び出さなければ動作しません。 – jdarthenay