Bit extension occuring when trying to store a “byt

2019-06-09 00:24发布

问题:

So I currently need to read in a string of hex ASCII characters and use them to determine a specific opcode. To do so I open a text file(its not really but for simple explanation we'll call it that) then read in the line. So if I get a line like 40f1... I have the function read the 2 characters and store them as an unsigned int into mem_byte. Then I cast it into a char to use as an array and retain the "byte" worth of information or the numerical value of two hex digits which were obtained by reading in ASCII character representation of 2 hex digits.

void getInstructions(FILE* read_file, int* stack_point, char** instructions, int size)
{
unsigned int mem_byte;
int ins_idx = 0;
char* ins_set = malloc(sizeof(char) * size);        //Set size of the array of bytes for memory. Temporarily holds the memory of the program

fscanf(read_file, "%d", stack_point);

//Reading in the memory from the program file
fscanf(read_file, " %2x", &mem_byte);       //Initial read to clear whitespace
ins_set[ins_idx] = (char) mem_byte;
ins_idx++;

while(fscanf(read_file, "%2x", &mem_byte) != 0) //Loops and reads 1 byte at a time until the fscanf hits the whitespace/end of the line its reading
{
    ins_set[ins_idx] = (char) mem_byte;
    printf("Byte: %x\n", ins_set[ins_idx]);
    ins_idx++;
}

strcpy(*instructions, ins_set);         //Copy the instruction set back to the original pointer for memory
free(ins_set);

return;

}

So the problem I run into is that if I print out the test results, I get

Byte: 40
Byte: fffffff1

Which means that the code is extending the char into a 4 byte data type. I am not sure whether or not the char is holding information from the unsigned int and prints it out or I am misunderstanding how %x or how type casting works. I would like to have my char instructions array to hold only 2 hex digits worth of information and nothing more.

回答1:

Arguments of type char, short, etc get implicitly converted to int when they're passed to variadic functions such as printf.

Thus, a negative value of one of those types will be sign-extended so that it holds the same value of type int; -1 as a char (which is commonly 0xFF as an unsigned char) will be implicitly converted to -1 as an int (which it seems would hold an underlying representation of 0xFFFFFFFF on your system).

Consider casting your argument to unsigned char to mitigate the sign extension you've noticed.

e.g. printf("Byte: %x\n", (unsigned char) ins_set[ins_idx]);