2016-04-08 42 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