2016-02-26 20 views
1

我试图读取包含82503x1200矩阵中的双格式化数字的文件。我正在阅读文件,但没有找到指定lseek正在使用的号码大小的方法。为什么给我那个数字而不是文件号?C++:lseek给予原始文件不同的值:

float fd; 
float ret; 
float b; 
const size_t NUM_ELEMS = 11; 
const size_t NUM_BYTES = NUM_ELEMS * sizeof(float); 

fd = open("signal_80k.txt",O_RDONLY); 
if(fd < 0){ 
    perror("open"); 
    //exit(1); 
} 

ret = lseek(fd, seekCounter*NUM_BYTES, SEEK_SET); 
ret = read(fd, &b, sizeof(float)); 
cout<<"> " << seekCounter << ": " << b<<endl; 
seekCounter++; 
close(fd); 

它打印:

0:1.02564e-08 1:1.08604e-05 2:0.000174702 3:6.56482e-07 4:2.57894e-09

但前值: 9.402433000000000e 8.459109000000000e 8.947654000000000e + 03 9.021620000000000e

这是它的外观在MATLAB

enter image description here

+1

你的代码看起来像你正在阅读的二进制数据,但你的文件扩展名是TXT这表明它是文本数据。 – Daniel

+0

嗨丹尼尔,是的,它是文本数据...这意味着lseek不是正确的方法? – Dazzid

+0

你的文本文件是怎样的? – Daniel

回答

2

在你的意见,你澄清说,该文件包含文本数据,我的回答是基于这一点。现在,让我们来看看文件中的第一个数字:

1.02564e-08 

有几个字符?我计数11个字符。然后,它后面有一个空格,所以在这之后的下一个值将是第一个之后的十二个字符。

通过不定期检查,我们发现您的代码设置

const size_t NUM_ELEMS = 11; 

为每列值的数量。

那么你的代码将

const size_t NUM_BYTES = NUM_ELEMS * sizeof(float); 

要计算每个行占用的字符数。现在,我可能错过了这些常量的实际含义,但无论如何,您在文件中都有一个目标值,并且您正试图直接寻找它,这就是底线。所以,为了这个答案的目的,我会去解释这个问题,但答案依然如此,无论如何。

流行测验为你。什么是sizeof(float)

答案:它是4字节,在大多数实现(所以我会假设前进)。因此,您计算每行将会有44个字符,并且您可以使用它来尝试查找文件中的相应行。至少,我是如何解析你的代码的。

问题当然是,假设每个值都以科学计数法表示,每行有11个值,每个值占用12个字符(包括尾随空格或换行符),每行都会实际上需要11 * 12或132个字符,而不是44.如果您使用的是使用\ r \ n作为新行的实现O/S,请再添加一个字符。

所以,你需要做一些调整。甚至在此之后,这整个卡片的房子取决于文件中的每个值始终以科学记数法表示,并具有相同的精度。

这是一个你不能真正做出的假设。此外,这不是唯一的问题。

第二个问题是您正试图将文件的内容直接读入float数据类型。是的,每个float数据类型将是四个字符,因为这是代表二进制文件中值为float的字节数。这里的问题是该文件不包含原始二进制数据,而是包含文本数据。

总之,我没有在这里看到很多选择,只是从头到尾阅读文件,而不是尝试寻找正确的位置,因为您不能保证文件中的每个值都会占用相同的位置字符数量;然后将文件作为文本读取,并使用operator>>将其内容转换为float值。

0

如果文件是二进制的,那么lseek会是合适的方法吗?

我改变做法,以这样的:

ifstream inFile("signal_80k.txt"); 
string line; 
int count = 0 ; 
if(!inFile.is_open()) 
{ 
    cout<<"\n Cannot open the signal_80k.txt file"<<"\n"; 
} 
else 
{ 
    cout<<"loading all data... "<<"\n"; 
    while(getline(inFile , line)){ 
     vector<string> numbers = ci::split(line, " ", false); 
     for(int i = 0; i <numbers.size(); i++){ 
      try{ 
       float thisNumber = std::stof(numbers.at(i)); 
       cout<<"numbers at: " << " = "<< thisNumber <<"\n"; 
      } 
      catch (...){ 
      } 
     } 
     count++; 
     cout<<"done: "<<count<<"\n"; 
    } 
    cout<<"all data ready!"<<"\n"; 
    inFile.close(); 
}