-1

I have this working code that assigns fixed values to some unsigned char variables:

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


int main2() 

{   
 unsigned char a,b;
    a=1,b=2;
    a=(a+b)/2;
    printf("\nAverage: %d\n%18d",a,sizeof(a));  

return 0;
}

But when I try reading in the values instead, like so:

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


int main() 

{   
 unsigned char a,b;
    scanf(" %d", &a);   scanf(" %d", &b);
    a=a,
    b=b,
    a=(a+b)/2;
    printf("\nAverage: %d\n%18d",a,sizeof(a));  

return 0;
}

it doesn't work. Why not? It seems that scanf takes only the last value when I print the sum.

This is my best attempt to fix the code:

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


int main()
{
unsigned char b;
unsigned short int a;
    scanf(" %u", &a);
    scanf(" %u", &b);
    b=b;{

    b=(a+b);
unsigned short int a;
    scanf(" %u", &a);{  
    
    
    b=(a+b)/3;
    printf("\nAverage: %u",b);  
    printf("\n   sizeof: %d",sizeof(b));
    
    
    }
            
}
return 0;   
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • 1
    `scanf` with `%d` or `%u` will fill 32-bit value. Which means UB - you give it pointer to 8-bit. Next 3 bytes will be damaged. – i486 Mar 22 '23 at 09:10
  • 2
    What do you think the assignments `a=a` and `b=b` will do? Why are you using the comma-operator? If you want to do separate statements, use actual statements with the statement terminator `;`. – Some programmer dude Mar 22 '23 at 09:12
  • As for your problem, perhaps [a good `scanf` reference](https://en.cppreference.com/w/c/io/fscanf) might help? The `%u` format is for an `unsigned int` argument. And never forget to check what `scanf` (and related functions) actually returns. – Some programmer dude Mar 22 '23 at 09:13
  • 3
    Welcome to Stack Overflow. "i know the a unsigned char is able to store at most 255, but im ok with that range" - in your own words, where the code says `scanf(" %d", &a);`, exactly what do you think the `%d` part means? How are you expecting `scanf` to *know about* the size limit on `a`? And *why* are you restricting the variable size like this, when it is easier to type `int`? (If your answer is "to save memory", then this is misguided in **several** ways.) – Karl Knechtel Mar 22 '23 at 09:28
  • @Luca Fiorentino Heredia, "This is my best attempt to fix the code:" --> why `b=(a+b)/3;` instead of `b=(a+b)/2;`? – chux - Reinstate Monica Mar 22 '23 at 10:43
  • 1
    This is the 3rd "wrong format specifier in printf/scanf" today. We need a canonical duplicate for closing these. They are also evidently of no use for future readers since the same FAQ keeps getting asked over and over. – Lundin Mar 22 '23 at 10:46

2 Answers2

2

From the C Standard (7.21.6.2 The fscanf function)

13 If a conversion specification is invalid, the behavior is undefined.

And you are using invalid conversion specifiers with declared objects as for example:

unsigned char a,b;
scanf(" %d", &a);   scanf(" %d", &b);

The conversion specifier d is designed to deal with objects of the type int not with objects of the type unsigned char.

Instead you need to write:

unsigned char a,b;
scanf(" %hhu", &a);   scanf(" %hhu", &b);

or instead of:

unsigned short int a;
scanf(" %u", &a);{  

you need to write:

unsigned short int a;
scanf(" %hu", &a);{  

Also the sizeof operator returns values of the type size_t. So to output such values you need to use the conversion specifier zu instead of d:

printf("\nAverage: %d\n%18zu\n",a,sizeof(a)); 

or for example:

printf("\n   sizeof: %zu\n",sizeof(b));
xihtyM
  • 240
  • 1
  • 2
  • 9
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
1

General advice: take warnings to heart when compiling. Copying and pasting your code gave me the following:

main.c:8:14: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘unsigned char *’ [-Wformat=] 8 | scanf(" %d", &a);

So taking all warning into account, I can re-order your first program to this (which works!):

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

int main()
{
    int a, b;
    scanf(" %d", &a);
    scanf(" %d", &b);
    // a = a, --> has no effect
    // b = b, --> has no effect
    a = (a + b) / 2;
    printf("\nAverage: %d\n%18d", a, sizeof(a));
    return 0;
}

If you really do want to use unsigned chars, go with %hhu:

unsigned char a, b;
scanf(" %hhu", &a);
scanf(" %hhu", &b);
Evert_B
  • 193
  • 5