为什么fgetpos()返回负偏移量?

时间:2011-01-18 21:05:26

标签: c

当我使用fgetpos(fp,&pos)时,通话会将pos设置为负值,其中pos的类型为fpos_t。有人可以解释为什么会这样吗?

#include<stdio.h>
#include<string.h>
#include<stdlib.h>


#define TRUE 1
#define FALSE 0

#define MAX_TAG_LEN 50

char filename[1000] = "d:\\ire\\a.xml";

//extract each tag from the xml file
int getTag(char * tag, FILE *fp)
{
    //skip until a beginning of a next
    while(!feof(fp))
        if((char)fgetc(fp) == '<')break;

    if(!feof(fp)){
        char temp[MAX_TAG_LEN]={0};
        char *ptr;
        int len;
        fpos_t b;
        fgetpos(fp,&b);   // here the b is containing -ve values.....???
        fread(temp,sizeof(char),MAX_TAG_LEN - 1,fp);
        temp[MAX_TAG_LEN-1] = 0;
        ptr = strchr(temp,'>');  //search of ending tag bracket
        len = ptr - temp + 1;
        sprintf(tag,"<%.*s",len,temp); //copy the tag
        printf("%s",tag); //print the tag
        b += len;         //reset the position of file pointer to just after the tag character.
        fsetpos(fp,&b);

        return TRUE;
    }
    else{
        return FALSE;
    }
}



int main()
{
    int ch;
    char tag[100]={0};
    FILE *fp = fopen(filename,"r");

    while(getTag(tag,fp)){
    }

    fclose(fp);

    return 0;
}

其中a.xml是一个非常基本的xml文件

<file>
  <page>
    <title>AccessibleComputing</title>
    <id>10</id>
    <redirect />
    <revision>
      <id>133452289</id>
      <timestamp>2007-05-25T17:12:12Z</timestamp>
      <contributor>
        <username>Gurch</username>
        <id>241822</id>
      </contributor>
      <minor />
      <comment>Revert edit(s) by [[Special:Contributions/Ngaiklin|Ngaiklin]] to last version by [[Special:Contributions/Rory096|Rory096]]</comment>
      <text xml:space="preserve">#REDIRECT [[Computer accessibility]] {{R from CamelCase}}</text>
    </revision>
  </page>

  </file>

该代码适用于某些xml文件,但对于上述xml文件,它在打印第一个标记后停止。

2 个答案:

答案 0 :(得分:9)

根据the cplusplus.com description of fpos_t

  

fpos_t个对象通常是通过调用fgetpos创建的,它会返回对此类对象的引用。 fpos_t的内容不应直接读取,而只是在调用fsetpos时将其引用用作参数。

我认为这意味着理论上fpos_t的价值可以是任意正面或负面的,只要实施正确对待它。例如,fpos_t可能偏离文件的 end 而不是开头,在这种情况下负值是有意义的。它也可能是一些奇怪的位打包表示,它将使用每个位(包括符号位)来编码有关文件位置的其他信息。

答案 1 :(得分:0)

最后我发现了错误......

msdn说

  

您可以使用fseek重新定位   指针在文件中的任何位置。该   指针也可以定位在外面   文件的结尾。 fseek清除了   文件结束指示并否定   任何先前的ungetc调用的效果   反对流。

     

打开文件进行追加时   数据,当前文件的位置是   由最后一次I / O操作决定,   不是下一次写的地方   发生。如果还没有I / O操作   发生在打开的文件上   附加,文件位置是   文件的开头。

     

对于以文本模式打开的流,fseek的用途有限,因为   回车换行翻译   会导致fseek产生意外   结果。唯一的fseek操作   保证在打开的流上工作   在文本模式下是:

     

寻找0相对偏移量   任何原点值。求   从文件的开头用   从调用返回的偏移值   FTELL。

一旦fopen调用从“r”修改为“rb”,它工作正常....

感谢