-1

I'm trying to write a program that takes a file, and reads bytes from it in different intervals, and assigns them to a variable. This is what I currently have:

struct casc_file_parsed {
    unsigned int targetsize;
    uint64_t blocksize;
    uint64_t blockcount;
    csc_block_t* blocks;
};
struct casc_file_parsed parsed_casc_file;
FILE* fpc = fopen(casc_file_data, "r");

char c;
char str[MAX];
int i = 0;
int j = 0;

for(i = 0; i >= 24; i++) {
    if(i >= 16 && i <= 24) {    
        str[j] = c;
        j++;
    }
    c = fgetc(fp);
}
parsed_casc_file.targetsize = str;

I haven't tested it yet, since I know it isn't complete yet, and other functionalities needs to be added before it can run. What I am trying to do in this approach is creating a loop, and if I is the interval of 16-24, it saves the current byte to an array str. The array then needs to be transformed into an int, and saved in the struct (I am aware that the bottom line won't work). I'm not sure if this is the best approach, but I could really use some input right now, if there is a better way or I am missing anything.

EDIT: The .cascade file is a 64-byte file, containing a list of hashes describing another file. The 16-24 bytes in this file, contains the file length of the original file, as an unsigned integer in network byte order.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 1
    Opening the file in text mode ("r") looks suspicious. – Passerby Nov 15 '21 at 13:41
  • @Passerby I'm not sure what you mean by suspicious, but I was thinking I only had to read from it, not write anything. I may actually have to use rb when I think about it. – ninjarubberband Nov 15 '21 at 13:46
  • It's unclear what the content of the `casc_file_data` file is. Is looks like you're reading some string from the file and then you consider that string as an `unsigned int` which is totally wrong. Maybe you need to use `strtol`? Then you need to terminate your `str` string with a null character. Anyway there is not enough information in your question, it's unlikely that someone is able to answer. – Jabberwocky Nov 15 '21 at 13:46
  • @Jabberwocky I should have mentioned that, yes. I've updated my question. – ninjarubberband Nov 15 '21 at 13:51
  • 2
    I'd expect to see code using `fseek()` and `fread()` rather than iterating using `fgetc()`. It won't matter much with a file of 64 bytes; it won't matter much if the start offset is small, but there'd be an enormous difference if the file is 64 MiB and the start offset is some 10s of MiB. – Jonathan Leffler Nov 15 '21 at 13:55
  • @JonathanLeffler I tried going for that approach is as well, but then I found some code that tried doing it this way. All the .cascade files I have to parse is 64 bytes, then won't be smaller or larger. – ninjarubberband Nov 15 '21 at 14:00
  • 1
    If you're only ever dealing with files of 64 bytes in total, simply allocate a buffer of 64 bytes and read the whole file into memory with one `fread()`. Fiddle with the byte array as needed afterwards. – Jonathan Leffler Nov 15 '21 at 14:12
  • 2
    `for(i = 0; i >= 24; i++)` does not loop at all, because `0 >= 24` is false. – mch Nov 15 '21 at 14:14

1 Answers1

1

You probably need something like this:

  ...
  FILE* fpc = fopen(casc_file_data, "rb");  // use "rb" just to be sure you're reading
                                            // binary. It's mandatory on some platforms

  fseek(fpc, 16, SEEK_SET);        // goto offset 16
  char buffer[8];                  
  fread(buffer, 8, 1, fpc);        // read 8 bytes (which are a 64 bit integer)

  uint64_t rawsize;
  memcpy(&rawsize, buffer, 8);     // copy bytes read to 64 bit variable

  unsigned int targetsize = (unsigned int)rawsize;  // convert to unsigned int
  ...
  fclose(fpc);

Disclaimers:

  • I suppose that the 8 bytes in offsets 16 to 24 are actually a 64 bit number
  • You may need to deal with endiannes.
  • There is no error checking whatsoever in this example.
Jabberwocky
  • 48,281
  • 17
  • 65
  • 115