3

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;
}
gamalanwer
  • 31
  • 1
  • 5

1 Answers1

4

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);
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • im relatively new, so.. Im using Code::Blocks v16.01 and from what i can see its using GNU GCC. also %hhu gave error so i assume it that. can i change something to make it use C99 or C11. also If you will can you give me a reference on how to use SCNu8 and PRIu8 – gamalanwer Aug 31 '16 at 11:26
  • Are you running CodeBlocks on a Unix-based system (Linux, Mac, BSD, etc) or on Windows? If, as I suspect, you're on Windows, then the issue is whether the runtime library supports the `hh` notation. You may have better luck than me (Google's just decided to serve me Russian pages), but [`scanf()` width specification](https://msdn.microsoft.com/ru-ru/subscriptions/xdb9w69d(v=vs.90).aspx) may help — the text is mostly English; it doesn't list `hh` which isn't a big surprise as the MS runtime is not completely C99 compliant. – Jonathan Leffler Aug 31 '16 at 11:33
  • MS, Unfortunately. can I use SCNu8 and PRIu8? and if so, how? thanks in advance. – gamalanwer Aug 31 '16 at 11:48
  • The test for `g_temp < 0` is pointless because `g_temp` is an unsigned type and can never be negative. GCC will point that out if asked. You should normally put the increment in the for-control line: `for (gr_c = 0; gr_c < 3; gr_c++)` rather than have the empty increment at the top and putting the increment at the tail of the loop. Note that the suffix `_t` is usually denotes a type (e.g. `uint8_t` in ``), not a variable, and the suffix should be treated as reserved. (See [What does a type followed by `_t` (underscore-t) represent?](http://stackoverflow.com/questions/231760/)). – Jonathan Leffler Aug 31 '16 at 22:10