uint8 с scanf и printf в C

Этот блок кода является частью более крупного кода базы данных на C. Эта часть оценивается студентами. Требования заключаются в использовании typedef unsigned char uint8 вместо простого int. На всю жизнь я не могу заставить это работать. Когда я использую %c в scanf, он пропускает. В печати, если иногда печатает первую цифру. Итак, это код с int, и он работает нормально, как мне заставить его работать с uint8 или 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;
}

person gamalanwer    schedule 31.08.2016    source источник
comment
Добро пожаловать в Stack Overflow. Обратите внимание, что предпочтительный способ сказать «спасибо» здесь — проголосовать за хорошие вопросы и полезные ответы (если у вас достаточно репутации для этого) и принять наиболее полезный ответ на любой заданный вами вопрос (что также дает вы немного повышаете свою репутацию). См. страницу О, а также Как мне задавать вопросы здесь? и Что мне делать, когда кто-то отвечает на мой вопрос?   -  person Jonathan Leffler    schedule 01.09.2016


Ответы (1)


Вы хотите рассматривать unsigned char как небольшое целое число, а не как символ. Предполагая C99 или более позднюю версию, вы будете использовать:

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

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

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

hh в преобразовании scanf() указывает, что предоставленный указатель относится к (беззнаковому) char. Нет необходимости в соответствующем изменении в printf(), потому что u1 будет автоматически повышен до int. Однако при желании вы можете использовать:

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

Это сохраняет симметрию в printf() и scanf(). Я заметил, что макросы в <inttypes.h> не применимы напрямую. Такие макросы, как SCNu8 и PRIu8, применяются к uint8_t, а не к uint8. Тем не менее, их, вероятно, можно было бы использовать, и они, вероятно, будут работать нормально — при условии, что они вообще предусмотрены в <inttypes.h>:

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

printf("Value: %" PRIu8 "\n", u1);
person Jonathan Leffler    schedule 31.08.2016
comment
я относительно новичок, так что .. Я использую Code:: Blocks v16.01 и, насколько я вижу, он использует GNU GCC. также %hhu дал ошибку, поэтому я предполагаю, что это так. Могу ли я что-то изменить, чтобы он использовал C99 или C11. также Если вы можете дать мне ссылку о том, как использовать SCNu8 и PRIu8 - person gamalanwer; 31.08.2016
comment
Вы используете CodeBlocks в системе на базе Unix (Linux, Mac, BSD и т. д.) или в Windows? Если, как я подозреваю, вы работаете в Windows, проблема заключается в том, поддерживает ли библиотека времени выполнения нотацию hh. Возможно, вам повезло больше, чем мне (гугл только что решил предоставить мне русские страницы), но scanf() указание ширины может помочь — текст в основном английский; в нем нет hh, что не является большим сюрпризом, поскольку среда выполнения MS не полностью совместима с C99. - person Jonathan Leffler; 31.08.2016
comment
МС, к сожалению. можно ли использовать SCNu8 и PRIu8? и если да, то как? заранее спасибо. - person gamalanwer; 31.08.2016
comment
Проверка для g_temp < 0 бессмысленна, потому что g_temp является беззнаковым типом и никогда не может быть отрицательным. GCC укажет на это, если спросят. Обычно вы должны помещать приращение в строку for-control: for (gr_c = 0; gr_c < 3; gr_c++), а не пустое приращение вверху и помещать приращение в конец цикла. Обратите внимание, что суффикс _t обычно обозначает тип (например, uint8_t в <stdint.h>), а не переменную, и этот суффикс следует рассматривать как зарезервированный. (См. Что представляет собой тип, за которым следует _t (подчеркивание-t)?). - person Jonathan Leffler; 01.09.2016