Home > OS >  C hexadecimal formatting giving me extra digits
C hexadecimal formatting giving me extra digits

Time:03-08

I've been working on a small program to dump the hex values of a file, similar to od or hexdump, and I've ran into an issue when printing the values. For certain hex values, mostly ones with alphabetical characters as their second digit, it prints with 6 extra f digits before printing the actual number, instead of just printing a 2-width value like I had specified. I have confirmed that the values themselves are not unexpected in any way, it's the printing that's messing it up.

Code:

int main(int argc, char* argv[]) {
    FILE* dataFile = fopen(argv[1], "rb");
    int byteCount = 0;
    char currentByte = fgetc(dataFile);
    while (currentByte != EOF) {
        printf("d", byteCount);
        do {
            //print as hex
            printf(" x ", currentByte);
            //set up for next loop
            currentByte = fgetc(dataFile);
            byteCount  ;
        } while (currentByte != EOF && (byteCount) % 16 != 0);
        printf("\n");
    }
    printf("d\n", byteCount);
}

Output:

00000000 7f  45  4c  46  02  01  01  00  00  00  00  00  00  00  00  00 
00000016 03  00  3e  00  01  00  00  00  10  6b  00  00  00  00  00  00
00000032 40  00  00  00  00  00  00  00  08  23  02  00  00  00  00  00
00000048 00  00  00  00  40  00  38  00  0d  00  40  00  1f  00  1e  00
00000064 06  00  00  00  04  00  00  00  40  00  00  00  00  00  00  00
00000080 40  00  00  00  00  00  00  00  40  00  00  00  00  00  00  00
00000096 ffffffd8  02  00  00  00  00  00  00  ffffffd8  02  00  00  00  00  00  00
00000112 08  00  00  00  00  00  00  00  03  00  00  00  04  00  00  00
00000128 18  03  00  00  00  00  00  00  18  03  00  00  00  00  00  00
00000144 18  03  00  00  00  00  00  00  1c  00  00  00  00  00  00  00
00000160 1c  00  00  00  00  00  00  00  01  00  00  00  00  00  00  00
00000176 01  00  00  00  04  00  00  00  00  00  00  00  00  00  00  00
00000192 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
00000208 fffffff8  34  00  00  00  00  00  00  fffffff8  34  00  00  00  00  00  00

Does anyone know what's going on here?

CodePudding user response:

There are several problems here.

  • char is entirely unsuitable to hold raw binary data, because it has implementation-defined signedness and it often a signed type, see Is char signed or unsigned by default?. In fact char should only ever be used for text strings. Instead, you would normally use uint8_t. However... :
  • The EOF constant is of type int, so if you intend to compare something against EOF, it must be type int. fgetc is guaranteed to return characters as if they were unsigned char but converted to int - as it happens, int is large enough to hold all values of an unsigned char so int can be used here.
  • %x specifier for printf expects an unsigned int.

Fixes:

  • char currentByte -> int currentByte
  • printf(" x ", currentByte); -> printf(" x ", (unsigned int)currentByte);.
  • You must always check if fopen was successful and also fclose the file pointer when done. Also note that calling fopen directly on argv with no input sanitation is not acceptable in a professional program. You don't even know if argv[1] exists - the program needs a whole lot more error handling overall.
  •  Tags:  
  • c hex
  • Related