Question

I am new in programming and even more in c programming. I am trying to read a binary file and then do bitwise process. Sample of my code and how I have written my program so far.

#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;
}

When I am compiling the code I get the error message:

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

I tried to declare another value as:

unsigned int memory_int[4];

When I compile the code I get the warning:

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);

Although that I changed the %" PRIu32" to %u I still get this warning.

I know so far that when I am using typedef struct I can call the content by using name.parameter, and the program seems to be operating correctly when I call first.size the value when need it. But I encounter a problem when I am trying to bitwise because I am asking the value to be broken in bits. Theoretically it should be possible since I have define it as 32 bit, but practically I am missing something extremely small. I tried to assign another value as uint32_t and also as unsigned int size[4] both times not successfully. Can some explain to me the reason and how to solve this problem?

Was it helpful?

Solution

There are some things to be modified in your code.

First, use " " in the name of the file to be read, as the fopen synax is

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

This way, the filename [path] will be const char *

Second, add the following lines to your code [after the existing line].

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

It will help you handle some unexpected conditions like "File does not exist"

Third, declare memory_int as an array of unsigned int containing 4 elements.

unsigned int memory_int[4] = {0};

Finally, altogether, the code looks like this.

#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;
}

Hope this works!!

OTHER TIPS

In line printf ("This is first.size before sync_safe: %u\n", memory_int); : %u would be useful to print memory_int[0].

One way to print the four elements of memory_int would be to use %u %u %u %u.

I also changed some stuff in the bitwise operations. I prefered the %x (hexadecimal) specifier to display the output : It will be much easier to correct the output of bitwise operations.

#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;
}

Bye,

Francis

#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;
}

When I am compiling the code I get the error message:

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

The reason that I was getting this error was that I was trying to compile a string like an array. I defined it as uint32_t size and I was calling it as first.size[3]. Of course it would never work, because one is a simple string and the second one is an array.

This is the testing code I create as a sample to test and learn the most in order to solve my problem. Since I just started to learn programming I have a lot of things to read understand and learn.

I hope this sample of code and help somebody else as it did for me.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top