3
votes

This code unite is a part of a bigger code of a database in C. This part takes grades of students. requirements are to use typedef unsigned char uint8 instead of a simple int. For the life of me I can't make it work. When I use %c in scanf it skips. In print if it prints the first digit sometimes. So this is the code with int and it's working fine, how do I make it work with uint8 or unsigned char???

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <ctype.h>
#include <inttypes.h>
#include <string.h>
//typedef unsigned char uint8;
typedef unsigned int uint8;
int main(void)
{
    uint8 grades_t[3], gr_c, g_temp;
    for (gr_c = 0; gr_c < 3;)
        {
            printf("please enter the grade (0-100) of subject no%d: ", gr_c+1);
            scanf("%d", &g_temp);
            if (g_temp < 0 || g_temp > 100) //only accept values between 0-100
                {
                    printf("please enter valid grade from 0 - 100!\n");
                    gr_c --; //if value is out of range, decrement  
                }

            else //store value 
                {
                    grades_t[gr_c] = g_temp; 

                }
            gr_c++;
        }
        printf("grade = %d\n", grades_t[0]); //unite test
        printf("grade = %d\n", grades_t[1]);
        printf("grade = %d", grades_t[2]);
    return 0;
}
1
Welcome to Stack Overflow. Please note that the preferred way of saying 'thanks' around here is by up-voting good questions and helpful answers (once you have enough reputation to do so), and by accepting the most helpful answer to any question you ask (which also gives you a small boost to your reputation). Please see the About page and also How do I ask questions here? and What do I do when someone answers my question? - Jonathan Leffler

1 Answers

4
votes

You want to treat the unsigned char as a small integer, not as a character. Assuming C99 or later, you'll use:

unsigned char u1;  // Or, given typedef unsigned char uint8; uint8 u1;

if (scanf("%hhu", &u1) != 1)
    …oops…

printf("Value: %d\n", u1);

The hh in the scanf() conversion specifies that the pointer provided is to a (unsigned) char. There's no need for the corresponding change in the printf() because u1 will be promoted to int automatically. However, if you wish, you can use:

printf("Value: %hhu\n", u1);

This preserves the symmetry in printf() and scanf(). I observe that the macros in <inttypes.h> aren't directly applicable. The macros such as SCNu8 and PRIu8 apply to uint8_t, not to uint8. That said, they could probably be used and they'd probably work OK — assuming they are provided in <inttypes.h> at all:

if (scanf("%" SCNu8, &u1) != 1)
    …oops…

printf("Value: %" PRIu8 "\n", u1);