2013-07-11 2 views
2

이 바이너리 파일을 읽고 화면에 숫자를 인쇄하고 싶지만 이상한 문자가 인쇄됩니다. 이 바이너리 파일을 MATLAB에서 생성했습니다. 데이터를 올바르게 표시하려면 어떻게해야합니까?바이너리 파일 읽기

#include <iostream> 
#include <fstream> 
using namespace std; 

ifstream::pos_type size; 
char * memblock; 

int main() 
{ 
    ifstream file ("seg.bin", ios::in|ios::binary|ios::ate); 

    if (file.is_open()) 
    { 
     size = (int)file.tellg(); 
     memblock = new char [size]; 
     file.seekg (0, ios::beg); 
     file.read (memblock, size); 
     file.close(); 

     cout << "the complete file content is in memory"; 

     for (int i=0;i<size;i++) 
     { 
      cout<<memblock[i]<<endl; 
     } 
    } 
    else cout << "Unable to open file"; 
    return 0; 
} 
+0

다음과 같이하십시오 :'cout << (int) memblock [i] << endl;' – sgarizvi

+1

@ sgar91 원시 데이터의 타입이'char' 인 경우에만 그렇게 할 것입니다. OP는 데이터 유형이 무엇인지에 대해 말하지 않았다. – paddy

+0

메모리 누수를 막기 위해 [] memblock을 나중에 삭제하는 것을 잊지 마십시오 – Enigma

답변

0

파일에 저장된 데이터 유형을 알아야합니다. 예를 들어 double이라고 가정 해 보겠습니다. 이 경우, 당신은이 작업을 수행 할 수 있습니다 : 그것은 시작하는 double의 배열에 직접 읽는 것입니다 대략가는

for (int i = 0; i < size; i += sizeof(double)) 
{ 
    cout << *(double*)&memblock[i] << endl; 
} 

다른 방법을. 그것을 운동으로 남겨 둘 것입니다. 당신은 출력에 char의 인쇄하고

1

는 출력에서 ​​char의 표현은 문자, 당신은 std::cout에 보내는 문자 인쇄 가능하지 않은 경우 당신은 아무것도 볼 또는 일부의 경우 줄게 이상한 문자 (또는 경우에 따라 삐 소리가납니다.)을 보게됩니다.

std::cout << static_cast<int>(memblock[i]) << std::endl; 
      ^^^^^^^^^^^^^^^^ 

당신은 8 비트 크기의 데이터를 얻을 수 있습니다 데이터를 반복-인쇄하는 방법 (또는 char가 크기)의이 supose 보자

시도는 charint에 캐스팅 당신이 당신의 파일에 다음과 같은 데이터를 가지고 :

00000FFF 

귀하의 출력은 다음과 같습니다

0

0

255

15하지만 당신은 다른 크기 (예를 들어 int)의 데이터로 작업하는 경우 당신은 4095의 출력을 기대 (또는 0 데이터가 너비가 16 비트 인 경우 4095).

당신의 경우라면, 당신이 기대하고있는 데이터의 배열로 데이터를 읽으려고 '(

  • CONST로 sizeelements 선언을 :

    const ifstream::pos_type size = file.tellg(); // do not cast the size! 
    const size_t elements = size/sizeof(int); // <--- beware of the sizes! 
    memblock = new int [elements];    // Elements, not size 
    
    for (int i = 0; i < elements; ++i) // Elements! not size 
    { 
        std::cout << memblock[i] << std::endl; 
    } 
    

    또 다른 팁 읽기 후에 변경하지 않을 것임) :이 변수는 읽기 전용으로 취급하려는 의도를 당신과 직장 동료에게 보여줍니다.

  • , intsize 캐스팅 tellg()의 반환 유형을 사용하거나 auto 사용하지 마십시오 const auto size = file.tellg(); : 왜 다른 형식으로 캐스팅을? 당신이 전화하고있는 기능과 동일한 기능을 사용하십시오! 캐스트는 오버 헤드를 유발할 수 있습니다.
  • 변수를 사용하려는 장소와 가장 가까운 범위에서 선언하십시오. 코드가 읽기 쉽고 유지 관리가 쉽습니다.
0

memblock은 char 유형이므로 cout이 char print (ASCII 문자)를 만듭니다. 이 경우 원하는 것은 memblock 포인터를 필요한 유형의 포인터로 reinterpret_cast하는 것입니다. 는 두 번 필요하다고 :

size = (int)file.tellg(); 
memblock = new char [size]; 
file.seekg (0, ios::beg); 
file.read (memblock, size); 
file.close(); 
double * fileContent = reinterpret_cast<double *>(memblock); 
cout << "the complete file content is in memory"; 

int sizeOfFileContent = sizeof(memblock)/sizeof(double); 
for (int i=0; i<sizeOfFileContent; i++) 
{ 
    cout<<fileContent[i]<<endl; 
} 

를 사용하여 하나의 포인터가 여러 번 삭제하려고, 메모리를 회수하지!