문제

퓨즈를 사용하여 표준 이미지가 포함 된 디스크 이미지가 있습니다. SuperBlock에는 다음이 포함되어 있으며 다음의 원시 데이터를 반환하는 read_superblock (*buf) 함수가 있습니다.

Bytes 0-3: Magic Number (0xC0000112)
      4-7: Block Size (1024)
     8-11: Total file system size (in blocks)
    12-15: FAT length (in blocks)
    16-19: Root Directory (block number)
  20-1023: NOT USED

나는 C를 처음 접 했고이 프로젝트를 시작하기 위해이 프로젝트를 구조 나 일부 변수로 읽고 디버깅을 위해 printf를 사용하여 화면에 인쇄하는 간단한 방법이 무엇인지 궁금합니다.

나는 처음에 원시 데이터를 볼 수 있다고 생각하는 것과 같은 일을 생각하고 있었지만 이것이 사실이 아니라고 생각합니다. 또한 구조가 없으며 나는 또한 그것을 끔찍하게 잘못 보이는 문자열로 읽으려고 노력하고 있습니다. 내가 데이터를 가져 오기 위해. 구조를 지정하고 각 변수의 바이트 수를 정의하는 방법이 있습니까?

char *buf;
read_superblock(*buf);
printf("%s", buf);
도움이 되었습니까?

해결책

예, 나는 당신이 이것을 구조로 읽는 것이 더 좋을 것이라고 생각합니다. 유용한 데이터를 포함하는 필드는 모두 32 비트 정수이므로 표준 헤더 파일에 정의 된 유형을 사용하여 이와 같은 구조를 정의 할 수 있습니다. stdint.h):

typedef struct SuperBlock_Struct {
  uint32_t magic_number;
  uint32_t block_size;
  uint32_t fs_size;
  uint32_t fat_length;
  uint32_t root_dir;
} SuperBlock_t;

구조를 a에 던질 수 있습니다 char* 전화 할 때 read_superblock, 이와 같이:

SuperBlock_t sb;
read_superblock((char*) &sb);

이제 데이터를 인쇄하려면 다음과 같은 호출을 할 수 있습니다.

printf("%d %d %d %d\n",
  sb.magic_number,
  sb.block_size,
  sb.fs_size,
  sb.fat_length,
  sb.root_dir);

정수 데이터를 읽고 있기 때문에 이와 같은 기술을 사용할 때 플랫폼의 엔지니어를 알고 있어야합니다 (즉, 데이터를 읽을 때 바이트를 바꿔야 할 수도 있음). 첫 번째 필드에서 마법 번호를 빠르게 사용하여 결정할 수 있어야합니다.

일반적으로 캐스팅하지 않고 이와 같은 구조를 통과하는 것이 바람직합니다. 이를 통해 컴파일러의 유형 검사를 활용하고 캐스팅이 숨길 수있는 잠재적 인 문제를 제거 할 수 있습니다. 그러나 그것은 당신의 구현을 바꾸는 것을 수반 할 것입니다 read_superblock 데이터를 구조로 직접 읽습니다. 이것은 어렵지 않으며 표준 C 런타임 기능을 사용하여 수행 할 수 있습니다. fread (질문에 힌트를받은대로 데이터가 파일에 있다고 가정) :

fread(&sb.magic_number, sizeof(sb.magic_number), 1, fp);
fread(&sb.block_size, sizeof(sb.block_size), 1, fp);
...

다른 팁

여기에 추가 할 두 가지 사항 :

  1. 원시 데이터를 구조물로 끌어 당기면 구조물이 32 비트 부호없는 정수로 구성되어 있어도 구조물에 패딩이없는 것으로 설정하는 것이 좋습니다. GCC에서는이 작업을 수행합니다 #pragma pack(0) 구조물 정의 전에 #pragma pack() 그 후.
  2. 잠재적 인 엔디 니스 문제를 다루기 위해서는 ntohs() 그리고 ntohl(), 각각 16 비트 및 32 비트 값에 대해. 이러한 스왑은 네트워크 바이트 오더에서 바이트 순서로 호스팅됩니다. 이것들이 동일하다면 (x86 기반 플랫폼에 있지 않음) 아무것도하지 않습니다. 호스트에서 네트워크 바이트 주문으로 이동합니다 htons() 그리고 htonl(). 그러나이 데이터는 네트워크가 아닌 파일 시스템에서 나오기 때문에 Endianness가 문제인지 모르겠습니다. 예상되는 값 (예 : 블록 크기)을 16 진수에서 얻는 값과 비교하여 파악하기에 충분히 쉬워야합니다.

데이터를 성공적으로 복사 한 후에 데이터를 인쇄하는 것은 어렵지 않습니다. 데이터를 보유하는 데 사용하는 구조의 인스턴스가 SuperBlock_t_instance라고 가정합니다.

그런 다음 다음과 같이 필드를 인쇄 할 수 있습니다.

printf("Magic Number:\t%u\nBlock Size:\t%u\n etc", 
SuperBlock_t_Instance.magic_number, 
SuperBlock_t_Instance.block_size);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top