返回列表 回复 发帖

unix下的fseek函数问题

int fseek(FILE *stream, long int offset, int whence);
fseek函数在windows平台下的offset参数为负值时将指针向后移动,但在unix平台下(SunOS x4100 5.10 Generic_118855-33 i86pc i386 i86pc Solaris)offset参数为负值时将指针仍向前后移动

测试程序如下:

#include <stdio.h>
#include <string.h>
void main(void)
{
        char fn[10] = "test.txt";
        char c;
        int len=5;
        int where =0;
        FILE * p;
        p = fopen( fn, "r" );
        where=ftell( p );
        printf("Offset is %d\n", where );
        fseek( p, len, SEEK_CUR );
        where=ftell( p );
        printf("Offset is %d\n", where );
        c = fgetc( p );
        printf("%c\n",c);
        where=ftell( p );
        printf("Offset is %d\n", where );
        len = 0-len-1;
        fseek( p, 5, SEEK_CUR );
        where=ftell( p );
        printf("Offset is %d\n", where );
        c = fgetc( p );
        printf("%c\n",c);
        where=ftell( p );
        printf("Offset is %d\n", where );
}

$ cat test.txt
this is a text file
in the second line
This is the 3rd line!

运行结果是:

Offset is 0
Offset is 5
i
Offset is 6
Offset is 11
e
Offset is 12

请大家指点!!

回复 #1 danvy 的帖子

不好意思,程序中出现重大错误!

回复 #2 danvy 的帖子

以下程序在VC6中可以正确运行,但在unix上运行不正确,请大家指正:
cat main.c
#include <stdio.h>
#include <string.h>
#include "getcfg.h"
void main(void)
{
        char fn[10] = "test.txt";
        char line[100];
        int num=0;
        int len=0;
        FILE * p;
        p = fopen( fn, "r" );
        while( !feof(p) )
        {
                memset( line, 0, 100 );
                len = get_num_of_line( p );
                num = get_line( p, line );
                printf("%d:%s\n", len,line );
        }
}
-----------------------------------------------
cat getcfg.h
int get_line( FILE *p, char *line );
int get_num_of_line( FILE *p );
-----------------------------------------------------
$ cat getcfg.h
int get_line( FILE *p, char *line );
int get_num_of_line( FILE *p );
-bash-3.00$ cat getcfg.c
#include<stdio.h>
/*
FILE *p : input argument
char *line: output argument
return value:
-1: end of file
0: a blank line
>0: num of characters
*/
int get_line( FILE *p, char *line )
{
        unsigned char c;
        int i=-1;
        while( !feof(p) )
        {
                c=fgetc( p );
                if( c == 255 )       // if end of file
                {
                        return i;    // then return -1
                }
                else if( c == '\n' ) // if it's end of line
                {
                        c = 0;
                        break;
                }
                else
                {
                        line[++i] = c;
                }
        }
        i = i + 1;
        line = c;
        return i;
}
int get_num_of_line( FILE *p )
{
        unsigned char c;
        int i=0;
        int offset=0;
        int where=0;
        where = ftell( p );
        printf("Start at:%d\n", where );
        while( !feof(p) )
        {
                c=fgetc( p );
                if( c == 255 )
                {
                        break;
                }
                else if( c == '\n' )
                {
                        offset=-2;
                        break;
                }
                else
                {
                        i++;
                }
        }
        offset -= i;
        fseek( p, offset, SEEK_CUR );
        printf("Offset is %d\n", offset );
        where = ftell( p );
        printf("End at:%d\n", where );
        printf("Line length is %d\n", i );
        return i;
}
-----------------
cat test.txt
this is a text file
in the second line
This is the 3rd line!
--------------------
运行结果是:
Start at:0
Offset is -21
End at:61
Line length is 19
19:
VC6中的运行结果是:
Start at:0
Offset is -21
End at:0
Line length is 19
19:this is a text file
Start at:21
Offset is -20
End at:21
Line length is 18
18:in the second line
Start at:41
Offset is -21
End at:41
Line length is 21
21:This is the 3rd line!
问题解决!
其根本原因在于,windows 和 unix 的机制不同
在windows中一个回车('\n')占两个字节,但在unix中仅占一个字节
所以在get_num_of_line函数中,需要修改的部分是:
                if( c == 255 )
                {
                        break;
                }
                else if( c == '\n' )
                {
                        offset=-1;
                        break;
                }
                else
                {
                        i++;
                }
因此在编程中要注意区分windows和unix的细节部分。
靠!
要疯掉了!
将修改后的代码在VC中运行,居然也能得出正确的结果!
微软是怎么搞的?还是我的程序哪里有问题???

恳请高手指点!!!!
真是给气晕了,VC的运行结果还有些不一样:
offset=-1时:
Start at:0
End at:21
Offset is -20
End at:1
Line length is 19
19:his is a text file
Start at:21
End at:41
Offset is -19
End at:22
Line length is 18
18:n the second line
Start at:41
End at:62
Offset is -21
End at:41
Line length is 21
21:This is the 3rd line!

offset=-2时:
Start at:0
End at:21
Offset is -21
End at:0
Line length is 19
19:this is a text file
Start at:21
End at:41
Offset is -20
End at:21
Line length is 18
18:in the second line
Start at:41
End at:62
Offset is -21
End at:41
Line length is 21
21:This is the 3rd line!
返回列表