1

我是编程新手,甚至更喜欢 c 编程。我正在尝试读取二进制文件,然后进行按位处理。我的代码示例以及到目前为止我是如何编写程序的。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <inttypes.h> /* Use C99 format specifiers: "%" PRIu8 "\n", "%" PRIu32 "\n" */

typedef struct{
  uint32_t size; /* Unsigned int 4 bytes (32 bits) */
}mp3_Header;

int main (int argc, char *argv[]) {

mp3_Header first;
unsigned int memory_int[4];


FILE *file = fopen( "song.mp3" , "rb" );

/* 1 Byte flags + revision_number 1 Byte + major_version 1 Byte + header_id 3 Bytes = 6 */
if ( fseek( file , 6 , SEEK_SET ) == -1 ) {
  fprintf( stderr, "Not able to fseek at possition 6" );
  return EXIT_FAILURE;
}

if ( fread( memory_int , sizeof(memory_int) , 1 , file ) != 1) {
  printf("Could not read first.size\n");
  exit (0);
}

printf ("This is first.size before sync_safe: %u\n", memory_int);

first.size = (memory_int[3] & 0xFF) |
     ((memory_int[2] & 0xFF) << 7 ) |
((memory_int[1] & 0xFF) << 14 ) |
((memory_int[0] & 0xFF) << 21 );

printf ("This is first.size after sync_safe: %" PRIu32"\n", first.size);

fclose(file);
return 0;
}

当我编译代码时,我收到错误消息:

error: subscripted value is neither array nor pointer nor vector first.size = (first.size[3] & 0xFF) |

我试图将另一个值声明为:

unsigned int memory_int[4];

当我编译代码时,我收到警告:

warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 2 has type ‘unsigned int *’ [-Wformat=] printf ("This is memset memory_int: %u\n", memory_int);

尽管我将 %" PRIu32" 更改为 %u,但我仍然收到此警告。

到目前为止,我知道,当我使用时,我可以使用 name.parameter 调用内容,并且当我在需要时调用该值时typedef struct,程序似乎运行正常。first.size但是当我尝试按位时遇到问题,因为我要求将值分解为位。理论上它应该是可能的,因为我将它定义为 32 位,但实际上我错过了一些非常小的东西。我尝试将另一个值分配为 uint32_t 和 unsigned int size[4] 两次都没有成功。有人可以向我解释原因以及如何解决这个问题吗?

4

3 回答 3

1

在行printf ("This is first.size before sync_safe: %u\n", memory_int);%u将是有用的打印memory_int[0]

打印 的四个元素的一种方法memory_int是使用%u %u %u %u.

我还更改了按位运算中的一些内容。我更喜欢%x(十六进制)说明符来显示输出:更正按位运算的输出会容易得多。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <inttypes.h> /* Use C99 format specifiers: "%" PRIu8 "\n", "%" PRIu32 "\n" */

typedef struct{
    uint32_t size; /* Unsigned int 4 bytes (32 bits) */
}mp3_Header;

int main (int argc, char *argv[]) {

    mp3_Header first;

    unsigned int memory_int[4];

    FILE *file = fopen( "song.dat" , "rb" );

    /* 1 Byte flags + revision_number 1 Byte + major_version 1 Byte + header_id 3 Bytes = 6 */
    if ( fseek( file , 6 , SEEK_SET ) == -1 ) {
        fprintf( stderr, "Not able to fseek at possition 6" );
        return EXIT_FAILURE;
    }
    //printf("%u\n",sizeof(memory_int));
    if ( fread( memory_int , sizeof(memory_int) , 1 , file ) != 1) {
        printf("Could not read first.size\n");
        exit (0);
    }

    printf ("This is first.size before sync_safe: %x %x %x %x\n", memory_int[0],memory_int[1],memory_int[2],memory_int[3]);

    memory_int[0]=0x4212;
    memory_int[1]=0x4213;
    memory_int[2]=0x4214;
    memory_int[3]=0x4215;

    first.size = (memory_int[3] & 0x000F) |
            ((memory_int[2] & 0x000F) << 8 ) |
            ((memory_int[1] & 0x000F) << 16 ) |
            ((memory_int[0] & 0x000F) << 24 );

    printf ("This is first.size after sync_safe: %x\n", first.size);

    fclose(file);
    return 0;
}

再见,

弗朗西斯

于 2014-01-03T08:49:56.737 回答
1

您的代码中有一些内容需要修改。

首先" "在要读取的文件名中使用,因为fopen语法是

FILE *fopen(const char *path, const char *mode);

这样,filename[ path] 将是const char *

其次,将以下行添加到您的代码中 [在现有行之后]。

FILE *file = fopen("song.mp3" , "rb" );
if (!file)
        {
         printf("Unable to open the file for reading\n");
         exit (0);
        }

它将帮助您处理一些意外情况,例如“文件不存在”

第三,声明memory_int为一个unsigned int包含 4 个元素的数组。

unsigned int memory_int[4] = {0};

最后,代码看起来像这样。

#include <stdint.h>
#include <unistd.h>
#include <inttypes.h> /* Use C99 format specifiers: "%" PRIu8 "\n", "%" PRIu32 "\n" */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <inttypes.h> /* Use C99 format specifiers: "%" PRIu8 "\n", "%" PRIu32 "\n" */

typedef struct{
        uint32_t size; /* Unsigned int 4 bytes (32 bits) */
}mp3_Header;

int main (int argc, char *argv[]) {

        unsigned int memory_int[4] = {0};
        mp3_Header first;

        FILE *file = fopen("song.mp3" , "rb" );
        if (!file)
        {
                printf("Unable to open the file for reading\n");
                exit (0);
        }

        /* 1 Byte flags + revision_number 1 Byte + major_version 1 Byte + header_id 3 Bytes = 6 */
        if ( fseek( file , 6 , SEEK_SET ) == -1 ) {
                fprintf( stderr, "Not able to fseek at possition 6" );
                return EXIT_FAILURE;
        }

        if ( fread( memory_int , sizeof(memory_int) , 1 , file ) != 1) {
                printf("Could not read first.size\n");
                exit (0);
        }

        printf ("This is first.size before sync_safe: %u %u %u %u\n", memory_int[0],memory_int[1],memory_int[2],memory_int[3]);

        first.size = (memory_int[3] & 0xFF) |
                ((memory_int[2] & 0xFF) << 7 ) |
                ((memory_int[1] & 0xFF) << 14 ) |
                ((memory_int[0] & 0xFF) << 21 );

        printf ("This is first.size after sync_safe: %u\n", first.size);

        fclose(file);
        return 0;
}

希望这有效!

于 2014-01-03T08:59:19.253 回答
0
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <inttypes.h> /* Use C99 format specifiers: "%" PRIu8 "\n", "%" PRIu32 "\n" */

typedef struct{
  uint32_t size; /* Unsigned int 4 bytes (32 bits) */
}mp3_Header;

int main (int argc, char *argv[]) {

  mp3_Header first;
  unsigned int memory_int[4];
  uint32_t memory_int_2[4];
  char memory[4];
  unsigned char memory_2[4];


  FILE *file = fopen( "song.mp3" , "rb" );

  /* 1 Byte flags + revision_number 1 Byte + major_version 1 Byte + header_id 3 Bytes = 6 */
  if ( fseek( file , 6 , SEEK_SET ) == -1 ) {
    fprintf( stderr, "Not able to fseek at possition 6" );
    fclose(file);
    return EXIT_FAILURE;
  }

  if ( fread( memory_int , sizeof(memory_int) , 1 , file ) != 1) {
    printf("Could not read first.size\n");
    fclose(file);
    exit (0);
  }

  /* 1 Byte flags + revision_number 1 Byte + major_version 1 Byte + header_id 3 Bytes = 6 */
  if ( fseek( file , 6 , SEEK_SET ) == -1 ) {
    fprintf( stderr, "Not able to fseek at possition 6" );
    fclose(file);
    return EXIT_FAILURE;
  }

  if ( fread( &first.size , sizeof(first.size) , 1 , file ) != 1) {
    printf("Could not read first.size\n");
    fclose(file);
    exit (0);
  }

  /* 1 Byte flags + revision_number 1 Byte + major_version 1 Byte + header_id 3 Bytes = 6 */
  if ( fseek( file , 6 , SEEK_SET ) == -1 ) {
    fprintf( stderr, "Not able to fseek at possition 6" );
    fclose(file);
    return EXIT_FAILURE;
  }

  if ( fread( memory_int_2 , sizeof(memory_int_2) , 1 , file ) != 1) {
    printf("Could not read first.size\n");
    fclose(file);
    exit (0);
  }

  /* 1 Byte flags + revision_number 1 Byte + major_version 1 Byte + header_id 3 Bytes = 6 */
  if ( fseek( file , 6 , SEEK_SET ) == -1 ) {
    fprintf( stderr, "Not able to fseek at possition 6" );
    fclose(file);
    return EXIT_FAILURE;
  }

  if ( fread( memory , sizeof(memory) , 1 , file ) != 1) {
    printf("Could not read first.size\n");
    fclose(file);
    exit (0);
  }

 /* 1 Byte flags + revision_number 1 Byte + major_version 1 Byte + header_id 3 Bytes = 6 */
  if ( fseek( file , 6 , SEEK_SET ) == -1 ) {
    fprintf( stderr, "Not able to fseek at possition 6" );
    fclose(file);
    return EXIT_FAILURE;
  }

  if ( fread( memory_2 , sizeof(memory_2) , 1 , file ) != 1) {
    printf("Could not read first.size\n");
    fclose(file);
    exit (0);
  }

  printf ("This is memory_int[0] before sync_safe: %u %u %u %u\n", memory_int[0],memory_int[1],memory_int[2],memory_int[3]);
  printf ("This is first.size before sync_safe: %" PRIu32"\n", first.size);
  printf ("This is memory_int_2[0] before sync_safe with PRIu32: %" PRIu32" %" PRIu32" %" PRIu32" %" PRIu32"\n", memory_int_2[0],memory_int_2[1],memory_int_2[2],memory_int_2[3]);
  printf ("This is memory[0] before sync_safe: %d %d %d %d\n", memory[0],memory[1],memory[2],memory[3]);
  printf ("This is memory before sync_safe: %s\n", memory);
  printf ("This is memory_2[0] before sync_safe: %d %d %d %d\n", memory_2[0],memory_2[1],memory_2[2],memory_2[3]);
  printf ("This is memory_2 before sync_safe: %s\n", memory_2);

  first.size = (memory_int[3] & 0xFF) |
    ((memory_int[2] & 0xFF) << 7 ) |
    ((memory_int[1] & 0xFF) << 14 ) |
    ((memory_int[0] & 0xFF) << 21 );

  printf ("This is first.size after sync_safe: %" PRIu32"\n", first.size);

  first.size = (first.size & 0xFF);

  printf ("This is first.size after sync_safe: %" PRIu32"\n", first.size);

  first.size = (memory[3] & 0xFF) |
    ((memory[2] & 0xFF) << 7 ) |
    ((memory[1] & 0xFF) << 14 ) |
    ((memory[0] & 0xFF) << 21 );

  printf ("This is first.size after sync_safe: %" PRIu32"\n", first.size);

  first.size = (memory_2[3] & 0xFF) |
    ((memory_2[2] & 0xFF) << 7 ) |
    ((memory_2[1] & 0xFF) << 14 ) |
    ((memory_2[0] & 0xFF) << 21 );

  printf ("This is first.size after sync_safe: %" PRIu32"\n", first.size);

  fclose(file);
  return 0;
}

当我编译代码时,我收到错误消息:

错误:下标值既不是数组也不是指针也不是向量 first.size = (first.size[3] & 0xFF) |

我收到此错误的原因是我试图编译一个像数组一样的字符串。我将它定义为uint32_t size并且我称它为first.size[3]. 当然它永远不会起作用,因为一个是简单的字符串,第二个是一个数组。

这是我作为样本创建的测试代码,用于测试和学习最多,以解决我的问题。自从我刚开始学习编程以来,我有很多东西要阅读理解和学习。

我希望这个代码示例能像对我一样帮助其他人。

于 2014-01-04T23:02:12.980 回答