-1

I'm trying to get successive bytes to print on the screen for the file that I'm reading. The file that is being read in a .vdi file and I'm trying to display the size of the virtual drive in a printf format.

How can I display the integer values of the read in byte values from the file?

I'm still kind of fuzzy on how C works with the printf function. My code:

void get_file_size(u32 fd) {
    u8* HDDsize = (u8 *)malloc(8);

    if(HDDsize == NULL) {
        printf("Memory not allocated!");
    }

    lseek(fd,DRIVE_SIZE,SEEK_SET);
    read(fd,HDDsize,8);
    printf("The file system size is: %lli\n",
            HDDsize[7]+HDDsize[6]+HDDsize[5]+HDDsize[4]+
            HDDsize[3]+HDDsize[2]+HDDsize[1]+HDDsize[0]);
    free(HDDsize);
}
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • It seems very unlikely that a hard disk drive size is the sum of 8 bytes. Assuming all the bytes are 255, your maximum size would be 240 units. Perhaps you should check the format of your file again to see if those 8 bytes are ASCII characters, or (as your format string seems to indicate) a `long long int` in some format (for instance big or little endian). – infixed Mar 13 '17 at 22:13
  • They are in hexadecimal and little endian format. – Daniel Joseph Day Mar 13 '17 at 22:14
  • "How can I display the integer values of the read in bytes from a file" - `printf("The first byte is %i\n", HDDsize[0]);` ? – user253751 Mar 13 '17 at 22:22
  • Seems like a homework question right? At work we wouldn't bother reinventing the wheel. I'd go straight for Unix's `od`. Before you say I'm on Windows I like to point out there are a number of Unix on Windows freebies. e.g. the smallest one Git bash is becoming my favourite. – Stephen Quan Mar 13 '17 at 22:42

2 Answers2

0

What you are doing is just summing the values of all those bytes and then printing the resulting sum. Since those bytes are in an array, so they are consecutive in the memory, you can try something like this:

long long number = *((long long*)HDDSize);

so it will look at those 8 bytes as a long long variable. it might show it backwards though (so you will need to reverse that array).

Meccano
  • 537
  • 4
  • 8
  • Is there any sort of way to convert the total hexadecimal number to an integer value that can be displayed? I now realize that I was just summing up the numbers. There is no knowledge of place when you do this method. Is there some sort of function that can convert hex to an integer value? – Daniel Joseph Day Mar 13 '17 at 22:21
  • And if for some reason the host machine isn't little endian you can always get a call to `le64toh( number )` in there too – infixed Mar 13 '17 at 22:22
  • @DanielJosephDay A function that can convert hex to an integer value is `strtol` but that's not what you're looking for. – user253751 Mar 13 '17 at 22:23
  • What you are calling hexadecimal is merely binary. Integers are already binary. But sometimes one can covert between string of characters to binary or vice versa. Your `printf("%lld",number)` is doing that sort of thing. That's what the `%lld` means. print the `long long int` given as an argument, which would be a binary – infixed Mar 13 '17 at 22:26
0

To print a value of 4-bytes stored in little endian (least significant byte in lowest address), code needs to scale each byte, not simple add them up. Each byte is 256x more significant than the neighboring byte. Use:

#include <stdint.h>
#include <stdio.h>

void Print_Size4(int fd) {
  uint8_t HDDsize[4];

  if (lseek(fd, DRIVE_SIZE,SEEK_SET) == -1) return;
  if (read(fd, HDDsize, sizeof HDDsize) != sizeof HDDsize) return;

  printf("The file system size is: %lu\n",
      //                 LU --> insure all math is at least of unsigned long
      (((HDDsize[3] * 256LU + HDDsize[2]) * 256 + HDDsize[1]) * 256 + HDDsize[0]));
}

Better to use standard fixed types like uint8_t than u8. malloc() not needed.

I'll leave it to OP to make an 8-byte one-line solution. Hint: also use LLU or uint64_t math.

Maybe use a loop.

uint64_t size = 0;
for (unsigned i=sizeof HDDsize; i>0; i--) {
  size = size*256 + HDDsize[i-1];
}

Research <inttypes.h> to find the best printf() format specifier for uint64_t.

Community
  • 1
  • 1
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • Thank you very much! I appreciate the help. Once I figured out I was just adding up the numbers I realized that they needed mathematically converted to an integer. – Daniel Joseph Day Mar 13 '17 at 22:43
  • @DanielJosephDay The only tricks to wide number conversion are 1) correct endian, 2) is the math wide enough? (The default `int/unsigned` math may be insufficient.) – chux - Reinstate Monica Mar 13 '17 at 22:47