Search code examples
cioasciiunsigned-char

Shifting Extended ASCII codes


When assigning Extended ASCII codes to an unsigned char, I noticed that the values are shifted upwards when they are written to a file.

I condensed my code into this simple program to briefly present my question:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    unsigned char testascii[3];

    testascii[0] = 122;
    testascii[1] = 150;
    testascii[2] = 175;

    printf("%d\n", testascii[0]);
    printf("%d\n", testascii[1]);
    printf("%d\n", testascii[2]);

    return 0;
}

If I run this simple program, I get this terminal output:

122
150
175

This is correct.

If I now add the following to the above program:

FILE *f;
f = fopen("/mystuff/testascii", "wb");
if (f == NULL)
{
  printf("Error opening file\n");
  exit(1);
}
fwrite(testascii, 1, 3, f);
fclose(f);

It runs correctly but if I now go to the O/S and run:

od -c testascii

I get this output:

0000000   z 226 257
0000003

As you can see the Standard ASCII code (below 128) is correctly shown; however the Extended ASCII codes (above 127) are changed. I expect them to be 150 and 175 but they are 226 and 257.

If I remove the binary flag from the file open command, the result is still the same.

As a final check, instead of the binary print (fwrite), I changed the code again and looped through the array and did a fprintf of each item like this:

fprintf (fp, "%d", appendtxt[i]);

Here's the OD display for that:

0000000   1   2   2   1   5   0   1   7   5
0000011

This all tells me that the binary print (fwrite) isn't doing what I expected. It's my understanding the fwrite command writes the binary data to the file. In that case why does it successful write a value less than 128 but it fails with values equal to or greater than 128?

Environment: Code::Blocks 16.01 Centos 7.1

Note: I did find this similar question: fwrite with non ASCII characters but it didn't seem to help with my situation. I could be wrong. Please let me know if I missed something in that post?


Solution

  • You are printing in octal (that's what od does by default), 226 octal is 150 decimal.