Jump to content

C - Unsigned Char (format specifier)

Hi P
Go to solution Solved by Unimportant,
3 hours ago, wasab said:

you can simply use %d in a printf to print out their ascii values. Alternatively, you can cast them to an int 


#include <stdio.h>
#include <string.h>

typedef unsigned char* byte_pointer;

// if least significant 8 bits are the first byte then this means your cpu is little Endian
void show_bytes(byte_pointer start, size_t len) {
    int i;
    for (i = 0; i < len; i++) {
        printf("\nbyte %d: %.2x", i, start[i]);

    }
    printf("\n");
}

void show_int(int x){
    show_bytes((byte_pointer) &x, sizeof(int));
}


void show_float(float x){
    show_bytes((byte_pointer) &x, sizeof(float));
}


void show_pointer(void* x){
    show_bytes((byte_pointer) &x, sizeof(void*));
}

int main() {
    unsigned char x = 'A'; // 65
    unsigned char y = 'Y'; // 88

    unsigned int z = (unsigned int)(x + y);

    printf("decimal value is %d", z);
    printf("\nbytes in hexadecimals are\n");
    show_int(z);

    return 0;
}

 

The problem isn't in the printing but in the scanf.

 

7 hours ago, Hi P said:

I ran gcc -v and it says: gcc version 8.1.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project)

 

am I using an old one? (i seriously don't know), if so, how do I install or use C99 / C11?

 

I tried the following but it didn't work, it didn't compile :(

gcc -o -std=c99 test.exe test.c

 

 

The output filename should immediately follow the -o switch:

gcc -std=c99 -o test.exe test.c

That should compile. Even then it might not work as intended however, as the problem would be in the scanf implementation of the runtime library that is being used. I'd not worry about it and just use a regular int and %d.

I was reading about data types and I wanted to run a quick test.

 

All I wanted to do is store two integer values (below 255) in an unsiged char data type, add them up and print out the value, however it didn't work and I'm not sure why... according to wikipedia I'm using the correct format specifier %hhu

 

Spoiler

#include <stdio.h>

int main(void)
{
    unsigned char first, second;

    printf("First value: ");
    scanf("%hhu", &first);

    printf("Second value: ");
    scanf("%hhu", &second);

    printf("%hhu + %hhu = %hhu",
           first, second, first + second);
}

 

 

However I get the following output:

 

// (Values entered)
// First value: 5
// Second value: 10

// (Program Output)
// 0 + 10 = 10

 

It isn't storing the first variable, the thing is... I went ahead and commented-out the second variable for test purposes, and only then the program would successfully store the first variable.

 

What am I doing wrong?

 

Thank you :D

 

Link to comment
Share on other sites

Link to post
Share on other sites

24 minutes ago, Hi P said:

I was reading about data types and I wanted to run a quick test.

 

All I wanted to do is store two integer values (below 255) in an unsiged char data type, add them up and print out the value, however it didn't work and I'm not sure why... according to wikipedia I'm using the correct format specifier %hhu

 

  Hide contents


#include <stdio.h>

int main(void)
{
    unsigned char first, second;

    printf("First value: ");
    scanf("%hhu", &first);

    printf("Second value: ");
    scanf("%hhu", &second);

    printf("%hhu + %hhu = %hhu",
           first, second, first + second);
}

 

 

However I get the following output:

 


// (Values entered)
// First value: 5
// Second value: 10

// (Program Output)
// 0 + 10 = 10

 

It isn't storing the first variable, the thing is... I went ahead and commented-out the second variable for test purposes, and only then the program would successfully store the first variable.

 

What am I doing wrong?

 

Thank you :D

 

The hhu modifier was introduced in C99 and did not exist earlier. Using a modern version of gcc with the -std=c99 command line the program works as expected:

First value: 5
Second value: 10
5 + 10 = 15

You're probably using a compiler/runtime library that does not support the hhu modifier and the second scanf overwrites the first value in memory. Simplest fix is to use a normal int.

Link to comment
Share on other sites

Link to post
Share on other sites

7 hours ago, Unimportant said:

The hhu modifier was introduced in C99 and did not exist earlier. Using a modern version of gcc with the -std=c99 command line the program works as expected,

tou're probably using a compiler/runtime library that does not support the hhu modifier and the second scanf overwrites the first value in memory.

I ran gcc -v and it says: gcc version 8.1.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project)

 

am I using an old one? (i seriously don't know), if so, how do I install or use C99 / C11?

 

I tried the following but it didn't work, it didn't compile :(

gcc -o -std=c99 test.exe test.c

 

 

Link to comment
Share on other sites

Link to post
Share on other sites

you can simply use %d in a printf to print out their ascii values. Alternatively, you can cast them to an int 

#include <stdio.h>
#include <string.h>

typedef unsigned char* byte_pointer;

// if least significant 8 bits are the first byte then this means your cpu is little Endian
void show_bytes(byte_pointer start, size_t len) {
    int i;
    for (i = 0; i < len; i++) {
        printf("\nbyte %d: %.2x", i, start[i]);

    }
    printf("\n");
}

void show_int(int x){
    show_bytes((byte_pointer) &x, sizeof(int));
}


void show_float(float x){
    show_bytes((byte_pointer) &x, sizeof(float));
}


void show_pointer(void* x){
    show_bytes((byte_pointer) &x, sizeof(void*));
}

int main() {
    unsigned char x = 'A'; // 65
    unsigned char y = 'Y'; // 88

    unsigned int z = (unsigned int)(x + y);

    printf("decimal value is %d", z);
    printf("\nbytes in hexadecimals are\n");
    show_int(z);

    return 0;
}

 

Sudo make me a sandwich 

Link to comment
Share on other sites

Link to post
Share on other sites

3 hours ago, wasab said:

you can simply use %d in a printf to print out their ascii values. Alternatively, you can cast them to an int 


#include <stdio.h>
#include <string.h>

typedef unsigned char* byte_pointer;

// if least significant 8 bits are the first byte then this means your cpu is little Endian
void show_bytes(byte_pointer start, size_t len) {
    int i;
    for (i = 0; i < len; i++) {
        printf("\nbyte %d: %.2x", i, start[i]);

    }
    printf("\n");
}

void show_int(int x){
    show_bytes((byte_pointer) &x, sizeof(int));
}


void show_float(float x){
    show_bytes((byte_pointer) &x, sizeof(float));
}


void show_pointer(void* x){
    show_bytes((byte_pointer) &x, sizeof(void*));
}

int main() {
    unsigned char x = 'A'; // 65
    unsigned char y = 'Y'; // 88

    unsigned int z = (unsigned int)(x + y);

    printf("decimal value is %d", z);
    printf("\nbytes in hexadecimals are\n");
    show_int(z);

    return 0;
}

 

The problem isn't in the printing but in the scanf.

 

7 hours ago, Hi P said:

I ran gcc -v and it says: gcc version 8.1.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project)

 

am I using an old one? (i seriously don't know), if so, how do I install or use C99 / C11?

 

I tried the following but it didn't work, it didn't compile :(

gcc -o -std=c99 test.exe test.c

 

 

The output filename should immediately follow the -o switch:

gcc -std=c99 -o test.exe test.c

That should compile. Even then it might not work as intended however, as the problem would be in the scanf implementation of the runtime library that is being used. I'd not worry about it and just use a regular int and %d.

Link to comment
Share on other sites

Link to post
Share on other sites

 
 
 
2 hours ago, Unimportant said:

snip

my bad, i did not see op's code snippet. Maybe op can use getchar() if op just wants to add up two char and print out their ascii value. 

Sudo make me a sandwich 

Link to comment
Share on other sites

Link to post
Share on other sites

5 hours ago, Unimportant said:

The problem isn't in the printing but in the scanf, that should compile, Even then it might not work as intended however, as the problem would be in the scanf implementation of the runtime library that is being used. I'd not worry about it and just use a regular int and %d.

You were right, it compiled but still didn't work :(

 

Yea I just used the int type at the end of the day, it was just a test

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×