2

我有一个包含数据(有符号数)的文件,排列如下:

   291
 -1332
   912
   915
 -1347
   196
  1110
  -997
   120
  1017
  -775
  -443
   985
    13
  -690
   369
   673
  -826
   -14
   891
  -546...(thousands of lines)

我想使用一个函数,它将我的文件指针移动到 ex.1100 的特定行数

目前我正在使用以下代码跳过并转到特定的行/号

if (offset>0)//offset is number of destination line
{
 while(fscanf(f,"%d",&buffer)!=EOF) //f is file pointer ;Buffer is int variable
   { 
    i++;
    if(i==offset)
            break;
    }

}

我想使用比这更好的代码,因为随着偏移量的增加,这段代码需要更多的时间,有什么想法可以以简单的方式(并且时间更短)实现吗?

4

2 回答 2

1

如果您的所有数字(例如)长度为六个字符,并且\n每行末尾有一个换行符,则可以n通过 fseeking to 获取行号(从零开始)n * 7。第 0 行在偏移 0 处,第 1 行在偏移 7 处,第 2 行在偏移 14 处,依此类推。

同样,第 1100 行(第 1101 行)可以通过以下方式到达:

if (fseek (f, 7700L, SEEK_SET) != 0) {
    // something went wrong.
}
if (fscanf (f, "%d", &buffer) != 1) {
    // something else went wrong.
}

这适用于任何固定宽度的线,您只需根据线宽和行尾调整乘法因子(例如,DOS 编码可能有两个字符,\r\n)。

当然,您可能会发现将整个文件读入内存中的整数数组(取决于有多少个)是有利的,这样对数据的随机访问变得非常快 - 这是因为没有理由回到初始加载后的任何数据的文件。

于 2013-09-25T06:26:32.387 回答
1

你有一些选择。如果您必须保留一个数字文本文件,并且由于每一行都是可变长度,您可以:

  • mmap(内存映射)文件的内容并将行号索引到一个数组中。为此,您需要对文件进行一次传递并在每行开始处生成一个文件偏移数组。
  • 将文件重写为二进制数据(例如整数数组) - 因为每个整数都在 nth_int * sizeof(int) 处找到,所以查找起来更加紧凑和快速。您在开始时支付一次罚款以重新写入文件。
  • 很大程度上取决于您的环境和用例,这就是您更好的判断规则的地方。最重要的是,测试和衡量,看看它是否值得。
于 2013-09-25T07:04:14.933 回答