2016-06-14 2 views
3

저는 C++로 읽기를 원합니다. 내가 읽고 확인해야 할 첫 번째 것은 파일의 매직 넘버입니다. 0xABCDEF00C++는 파일에서 매직 넘버를 읽고 비교합니다.

내가 읽고 숫자 이런 식으로 비교

: 내 경우에는 그것은 진수-값입니다

ifstream input ("C:/Desktop/myfile", ios::binary); 
if (input.is_open()) { 
input.seekg(0, ios::beg); 
unsigned char magic[4] = {0}; 
input.read((char*)magic, sizeof(magic)); 

if(magic[0] == 0xAB && 
    magic[1] == 0xCD && 
    magic[2] == 0xEF && 
    magic[3] == 0x00) { 
    cout << "It's my File!" << endl; 
} else { 
    cout << "Unknown File!" << endl; 
} 
} 

이 아주 잘 작동을하지만, 전체 읽기 문자를 비교하는 방법은 무엇입니까 [] - 한 번에 배열? 이 방법처럼 :

unsigned int magicNumber = 0xABCDEF00; 
... same code for reading file as above ... 
Instead of checking each Array-Entry a way like this: 

if(magic == magicNumber) { 
    do something ... 
} 

같은 방법이 있는지 알고있는 것이 좋을 것이다 - 그렇지 않으면 덕분에 당신은 당신의 플랫폼의 엔디 언을 알고 있다면 그런 방법 :

+3

memcpy를 사용하여 char 배열의 내용을 부호없는 int로 복사 할 수 있습니다. 'memcpy (& anUnsignedInt, magic, sizeof (unsigned int)); ' – Christoph

+0

마법의 숫자가'long' 범위입니까? 그런 다음'std :: stol' 또는 익숙한 ('long'을'int','stoll'은'stoi', 부호없는 것은'i' /'l' /'ll' 앞에'u'를 추가하십시오.) ... –

+1

이진 파일에서 작동하지 않을 경우, @LapshinDmitry – user4581301

답변

2

그리운 여기에 도움이 될 수. 읽은 후에는 unsigned char magic[4] 당신은 단순히으로 비교를 수행 할 수 있습니다이 엔디 언 독립적 인

const unsigned char magicref[4] = {0xAB, 0xCD, 0xEF, 0} 
if (memcmp(magic, magicref, sizeof(magic)) == 0) { 
    // do something ... 
} 

.

당신은 당신이 직접 uint32_t로 모든 것을 처리 할 수 ​​있습니다, 당신이 플랫폼은 매직 넘버 당신을 줄 것이다 및 다른 플랫폼에 이식에 대한 상관 없어 무엇을 알고 있다면이 서로 다른 플랫폼에 이식 할 수 없습니다

uint32_t magic, refmagic = 0xABCDEF00; // big endian here... 
input.read(reinterpret_cast<char *>(&magic), sizeof(magic)); // directly load bytes into uint32_t 
if (magic == refmagic) { 
    //do something... 
} 

, 하지만 단순한 경우에 사용할 수 있습니다 굵은 빨간색 깜박이는 글꼴을 사용하여 의견을 말하십시오 BEWARE : 빅 엔디안 시스템에서만 사용

+0

처음 부분은 제게 가장 좋은 해결책이라고 생각합니다. 그것이 endianness 독립적 인 아주 좋습니다. 그러나'const char magicref [4] = {0xAB, 0xCD, 0xEF, 0}'는 const unsigned char magicref [4] = {0xAB, 0xCD, 0xEF, 0}'이 될 것입니다. 내가 어떤 컴파일러 경고와 같은 경우 : 경고 : 'int'에서 'const char'내부로 '237'의 변환을 좁히기 – Opa114

+1

완벽한 @ Opa114가되도록하려면 의미 상 문자가 아니기 때문에 실제로는 uint8_t가되어야합니다. – olivecoder

+0

@olivecoder 힌트를 주셔서 감사합니다.'unsigend char' 대신'uint8_t'를 사용하려고 시도합니다. – Opa114

0

이없는 저를 teeling 위해, 이를 수행하기 위해 uint32_t 변수를 사용할 수 있습니다. 조금 엔디안 시스템의 경우

이 사용

unit32_t number; 
input.read(reinpterpret_cast<char*>(&number), 4); 
if (number == 0x00EFCDAB) 
{ 
    cout << "It's my File!" << endl; 
} 

큰 엔디안 시스템의 경우, 사용 : memcmp

unit32_t number; 
input.read(reinpterpret_cast<char*>(&number), 4); 
if (number == 0xABCDEF00) 
{ 
    cout << "It's my File!" << endl; 
} 
1

이미 아주 좋은 답변이 있습니다! 여기에 표준 <algorithm> 라이브러리의 equal()을 사용하여 변형 기록을 보려면 :

unsigned char magic[4] = {0}; 
input.read((char*)magic, sizeof(magic)); 

const unsigned char code[4] = { 0xab, 0xcd, 0xef, 0x00 }; 
if(equal(code, code+sizeof(code), magic)) 
    cout << "It's my File!" << endl; 
else 
    cout << "Unknown File!" << endl; 

그것은 memcmp() 버전과 매우 유사하지만, 어떤 용기, 문자의뿐만 아니라 배열을 사용할 수 있습니다. 원래 원하는대로 다음

union magic_t { 
    uint8_t bytes[4]; 
    uint32_t number; 
}; 

을 :

Online demo

2

당신은 할 수

magic_t my_magic = {0xAB, 0xCD, 0xEF, 0}; 
magic_t file_magic; 
input.read((char *) file_magic.bytes, sizeof(file_magic)); 
if (file_magic.number == my_magic.number)... 

당신은 모든 엔디안 걱정 할 필요가 없습니다.

엔디안 번호에 따라 다르지만 실제로는 숫자가 0xABCDEF00이 아니더라도 항상 올바른 바이트 시퀀스가되므로 문제가되지는 않습니다.

또는 선택적으로 캐스팅을 사용할 수도 있습니다 (하지만 생각만큼 추울 것 같습니다).

+0

대체 솔루션도 있지만 약간의 비교를 위해 조금 복잡하다고 생각합니다. 하지만이 방법으로 할 수 있다는 것을 알면 좋습니다 :) – Opa114

+0

* 선택적으로 캐스팅을 사용할 수 있습니다 * 아니요, 일반적으로 [strict aliasing]을 위반하는 캐스팅을 사용할 수 없습니다 (http://stackoverflow.com)./questions/98650/what-is-the-strict-aliasing-rule) 따라서 정의되지 않은 동작입니다. 또한 정렬 제한이있는 하드웨어에서 SIGBUS를 제기 할 가능성이 있습니다. –

+0

그러나 주조 솔루션을 권장하거나 정교하지 않은 것을 관찰 해 주셔서 감사합니다. 이 코드는 스택 오버플로에 직접 작성되었으며 작동하지도 않습니다. 위의 답변 중 하나를 캐스팅 솔루션으로 확인하십시오. 공동 작업을 통해 개선 할 수도 있습니다. – olivecoder

관련 문제