C fseek-跳过大量字节失败?

C fseek-跳过大量字节失败?,c,fseek,C,Fseek,在使用fread读取下一个字节之前,我试图跳过大量字节。 当尺寸较小时#定义尺寸6404168-它可以工作: long int x = ((long int)size)*sizeof(int); fseek(fincache, x, SEEK_CUR); 当大小很大时,定义大小649218227,它不会:(下一个fread读取垃圾,无法真正理解它从哪个偏移量读取 使用fread作为解决方案在这两种情况下都有效,但速度非常慢: temp = (int *) calloc(size, sizeof

在使用
fread
读取下一个字节之前,我试图跳过大量字节。 当尺寸较小时
#定义尺寸6404168
-它可以工作:

long int x = ((long int)size)*sizeof(int);
fseek(fincache, x, SEEK_CUR);
当大小很大时,定义大小649218227,它不会:(下一个
fread
读取垃圾,无法真正理解它从哪个偏移量读取

使用
fread
作为解决方案在这两种情况下都有效,但速度非常慢:

temp = (int *) calloc(size, sizeof(int));
fread(temp,1, size*sizeof(int), fincache);
free(temp);

fseek
offset
参数必须是
long
,而不是
long
。因此
x
必须适合
long
,否则不要使用
fseek

fseek
offset
参数必须是
long
,而不是
long
x
必须适合
long
,否则不要使用
fseek

fseek输入指南:

抵消− 这是要从何处偏移的字节数

通过将
long-long
(其值大于
long-int
的最大值)传递给fseek而不是所需的
long
,可以调用未定义的行为


众所周知,UB可以做任何事情,包括不工作。

输入fseek指南:

抵消− 这是要从何处偏移的字节数

通过将
long-long
(其值大于
long-int
的最大值)传递给fseek而不是所需的
long
,可以调用未定义的行为


众所周知,UB可以做任何事情,包括不工作。

因为您的平台的
int
很可能是32位的,将649218227乘以
sizeof(int)
导致数值超过
INT\u MAX
LONG\u MAX
,这两个值在32位平台上都是2**31-1。由于
fseek
接受
LONG INT
,因此产生的溢出会导致程序打印垃圾

您应该查阅编译器的文档,以确定它是否为64位搜索提供了扩展。例如,在POSIX系统上,您可以使用,它接受类型为
off\t
的偏移量

在调用64位查找函数之前,请小心不要引入溢出。小心的代码可能如下所示:

off_t offset = (off_t) size * (off_t) sizeof(int);
fseeko(fincache, offset, SEEK_CUR);

因为您的平台的
int
很可能是32位,将649218227乘以
sizeof(int)
导致数值超过
INT\u MAX
LONG\u MAX
,这两个值在32位平台上都是2**31-1。由于
fseek
接受
LONG INT
,因此产生的溢出会导致程序打印垃圾

您应该查阅编译器的文档,以确定它是否为64位搜索提供了扩展。例如,在POSIX系统上,您可以使用,它接受类型为
off\t
的偏移量

在调用64位查找函数之前,请小心不要引入溢出。小心的代码可能如下所示:

off_t offset = (off_t) size * (off_t) sizeof(int);
fseeko(fincache, offset, SEEK_CUR);
假设
sizof(int)
4
并且您在32位系统上(其中sizeof(long)为4)

因此649218227*4将溢出long所能容纳的值。有符号整数溢出是未定义的行为。因此,您可以将其用于较小的值(小于long_MAX)

您可以使用循环代替
fseek()
必要的字节

long x;
intmax_t len = size;

for(;len>0;){    
   x = (long) (len>LONG_MAX?LONG_MAX:len);
   fseek(fincache, x, SEEK_CUR);
   len = len-x;
}
假设
sizof(int)
4
并且您在32位系统上(其中sizeof(long)为4)

因此649218227*4将溢出long所能容纳的值。有符号整数溢出是未定义的行为。因此,您可以将其用于较小的值(小于long_MAX)

您可以使用循环代替
fseek()
必要的字节

long x;
intmax_t len = size;

for(;len>0;){    
   x = (long) (len>LONG_MAX?LONG_MAX:len);
   fseek(fincache, x, SEEK_CUR);
   len = len-x;
}

试试这个,如果是这么大的数字,你可能必须把它读出来

 size_t toseek = 6404168;
 //change the number to increase it
 while(toseek>0)
 {
    char buffer[4096];
    size_t toread = min(sizeof(buffer), toseek);
    size_t read = fread(buffer, 1, toread, stdin);
    toseek = toseek - read;
 }

试试这个,如果是这么大的数字,你可能必须把它读出来

 size_t toseek = 6404168;
 //change the number to increase it
 while(toseek>0)
 {
    char buffer[4096];
    size_t toread = min(sizeof(buffer), toseek);
    size_t read = fread(buffer, 1, toread, stdin);
    toseek = toseek - read;
 }


偏移参数需要一个
long int
(不是
long
)@AlterMann,尝试更改为
long int
,但仍然不起作用。你是否也要取消演员阵容?还有返回值是多少,你真的应该检查一下……哎呀!你们是对的。我检查过了,一旦我将
x
更改为
long int
,它就会溢出到
-1698094388
,然后从
fseek
返回
is
-1
。我该怎么办?为什么
fread
没有出现此问题?offset参数需要
long int
(而不是
long
)@AlterMann,尝试更改为
long int
,但仍然不起作用。你是否也要取消演员阵容?还有返回值是多少,你真的应该检查一下……哎呀!你们是对的。我检查过了,一旦我将
x
更改为
long int
,它就会溢出到
-1698094388
,然后从
fseek
返回
is
-1
。我该怎么办?为什么
fread
没有遇到此问题?猜得好。尝试更改为
long int
,但仍然无效,因为
((long int)size)*sizeof(int)
大于允许存储在long中的最大值。请参阅
猜得好。尝试更改为
long int
,但仍然无效,因为
((long int)size)*sizeof(int)
大于允许存储在长整数中的最大值。请参阅
尝试更改为长整数,但仍然没有更改work@ihadanny您的大小是否适合C中的正常
long int
,将
long-long
传递给声明接受
long
的函数不是未定义的行为,除非数字超出对[LONG_MIN,LONG_MAX]范围进行反求。在该范围内,编译器将正确地将
LONG-LONG
值转换为
LONG
@user4815162342。不过,他传递的值超出了该范围。因此他调用了UBAGRED。修改后的答案不再包含错误的一般声明。(但它确实包含未关闭的参数。)