开发者

Why does fgetpos() return a negative offset?

When I am using fgetpos(fp,&pos), the call is setting pos to a negative value where pos is of type fpos_t. Can some one explain why this is happening?

#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;
}

where a.xml is a very basic xml file

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

The code is working for some xml files but for the above xml file it is stoping after printing the first tag.


According to the cplusplus.com description of fpos_t:

fpos_t objects are usually created by a call to fgetpos, which returns a reference to an object of this type. The content of a fpos_t is not meant to be read directly, but only to use its reference as an argument in a call to fsetpos.

I think that means that in theory the value of an fpos_t could be arbitrarily positive or negative, so long as the implementation treats it correctly. For example, fpos_t could be some offset from the end of the file rather than the beginning, in which case negative values make sense. It also could be some weird bit-packed representation that would use each bit, including the sign bit, to encode some other information about the file position.


Finally I found the error....

msdn says

You can use fseek to reposition the pointer anywhere in a file. The pointer can also be positioned beyond the end of the file. fseek clears the end-of-file indicator and negates the effect of any prior ungetc calls against stream.

When a file is opened for appending data, the current file position is determined by the last I/O operation, not by where the next write would occur. If no I/O operation has yet occurred on a file opened for appending, the file position is the start of the file.

For streams opened in text mode, fseek has limited use, because carriage return–linefeed translations can cause fseek to produce unexpected results. The only fseek operations guaranteed to work on streams opened in text mode are:

Seeking with an offset of 0 relative to any of the origin values. Seeking from the beginning of the file with an offset value returned from a call to ftell.

once fopen call is modified from "r" to "rb" it worked fine....

thanks

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜