2011-06-28 86 views
0

我有一個二進制文件,其中包含一個double類型的數字。
示例輸入文件可在這裏找到:www.bobdanani.net/download/A.0.0
我想閱讀文件並在其中打印數字。 這是我做了什麼:C++讀取包含數字類型雙精度的二進制文件

char* buffer; 
int length; 
string filename = "A.0.0"; 
ifs.open (filename.c_str(), ios::in | ios::binary); 
// get length of file: 
ifs.seekg (0, ios::end); 
length = ifs.tellg(); 
ifs.seekg (0, ios::beg); 
// allocate memory: 
buffer = new char [length]; 
// read data as a block: 
ifs.read (buffer,length); 
ifs.close(); 

cout.write (buffer,length); 
cout << buffer << endl; 

delete[] buffer; 

我也曾嘗試使用類型轉換打印數量時增加一倍,但我得到了奇怪的字符。做這個的最好方式是什麼?我需要這個二進制文件的數據作爲並行程序的函數的輸入。但是這不在這個問題的範圍之內。

+0

也許你需要在使用它之前初始化緩衝區,就像這樣:memset(buffer,0,length) –

+3

如果不知道文件中double的格式,就不可能回答這個問題。 「二進制」不是格式;而二進制double可以有許多不同的格式。 –

+2

另外,_binary_文件不太可能通過_text_字符(如空格/製表符)來分隔值。爲什麼你甚至需要分離? – MSalters

回答

3

雖然我可能是錯的,因爲你說的數字是由製表符/空格分隔,我願意這是實際的ASCII數據,而不是原始的二進制數據。因此,使用浮點值的最佳方法是使用ifstream對象上的operator>>,然後將其推入double。這將自動將輸入值轉換爲double值,因爲您所做的只會複製組成浮點值的字符字節,但它們本身不是浮點值。另外,如果你試圖以字符串的形式輸出你的緩衝區,你沒有明確地以null結尾,所以它會繼續讀棧直到它遇到一個空終止符,或者你由於訪問內存而出現分段錯誤操作系統不允許你訪問堆棧的頂部。但無論如何,最終,您的緩衝區不會是double數據類型的表示。

所以,你會碰到這樣的:

double my_double_val; 

ifs.open (filename.c_str()); 

if (ifs) 
{ 
    ifs >> my_double_val; 
} 
else 
{ 
    cerr << "Error opening file" << endl; 
} 

ifs.close(); 

cout << "Double floating point value: " << my_double_val << endl; 
+0

這適用於文本文件,但不適用於二進制文件。 –

+1

他說,他願意賭它的 – Gerstmann

+0

真實文本數據,並且由於OP提到,他的號碼是由製表/空格分隔,這聽起來不像是「二進制」的數據,而更像是ASCII數據,我猜可能被誤解爲二進制數據,因爲ASCII也只是一系列字節。我只是從來沒有聽說過所需的選項卡/空格分隔二進制格式的... – Jason

0
cout.write (buffer,length); 

不要這樣做!以上是要將二進制數據轉儲到標準輸出。

cout << buffer << endl; 

不要這樣做!上面的代碼將二進制數據轉儲到標準輸出爲零的第一個字節。如果沒有這樣的字節,這將繼續走過緩衝區的末端(所以未定義的行爲)。

如果緩衝區確實只包含雙打,只有雙打,你可以做一些討厭像

double * dbuf = reinterpret_cast<double*>(buffer); 
int dlength = length/sizeof(double); 
0

在C使用的系統功能調用++(假設你使用的UNIX操作系統),並通過'od -e filename'爲系統函數調用的參數。然後,您可以輕鬆管理它返回的值並讀取它們。這是一種方法。當然,還有很多其他的方法可以做到這一點。