C99 | (BItfield) Struct в Struct не работает, чтобы быть выбранным с помощью name1.name2.variable - PullRequest
0 голосов
/ 12 января 2019

Как исправить эту ошибку? Я хочу иметь массив, где я могу сканировать данные «студентов» и, следовательно, использовать структуры. Проблема в том, что структура битового поля в другой структуре терпит неудачу.

Есть ли способ исправить это, не изменяя большую часть кода? Только хочу исправить, что битовые поля (день, месяц и т. Д.) Могут быть выбраны.

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

#define MAX 10
#define MAXCHAR 30

char comma;

struct date {
    unsigned int day:5;         
    unsigned int month:4;
    unsigned int year:11;   //funktioniert bis yr 2047;
};

struct student {
        unsigned long matriculation_number;
        char first_name[MAXCHAR];
        char last_name[MAXCHAR];
        struct date birthdate;
}Student[MAX];

/*
void scan_student(void) {
b
} */

int main(void) {

    int i = 0;
    printf("------------------------------\nGeben Sie alle benötigten Daten ein\n");
    printf("Vorname: ");
    fgets(Student[i].first_name, MAXCHAR, stdin);

    printf("Nachname: ");
    fgets(Student[i].last_name, MAXCHAR, stdin);

    printf("Matrikelnummer: ");
    scanf(" %lu", &Student[i].matriculation_number);

    printf("Geburtstdatum (DD.MM.YYYY): ");
    scanf(" %u%c%u%c%u", &Student.birthdate.day, &comma, &Student.birthdate.month, &comma, &Student.birthdate.year);
    printf("\n");


    return EXIT_SUCCESS;
}

ERROR-Log:

student.c: In function ‘main’:
student.c:42:26: error: cannot take address of bit-field ‘day’
     scanf(" %u%c%u%c%u", &Student[i].birthdate.day, &comma, &Student[i].birthdate.month, &comma, &Student[i].birthdate.year);
                          ^
student.c:42:61: error: cannot take address of bit-field ‘month’
     scanf(" %u%c%u%c%u", &Student[i].birthdate.day, &comma, &Student[i].birthdate.month, &comma, &Student[i].birthdate.year);
                                                             ^
student.c:42:98: error: cannot take address of bit-field ‘year’
 &Student[i].birthdate.day, &comma, &Student[i].birthdate.month, &comma, &Student[i].birthdate.year);

Ответы [ 2 ]

0 голосов
/ 12 января 2019

Хотя вы не можете передать элементы битового поля в scanf, вы можете передать временные файлы в scanf и назначить их битовому полю без проблем:

unsigned char day = 0, month = 0;
unsigned short year = 0;
scanf(" %hhu%c%hhu%c%hu", &day, &comma, &month, &comma, &year);
Student.birthdate.day = day;
Student.birthdate.month = month;
Student.birthdate.year = year;

Обратите внимание, что для этого требуется сужение, поэтому у вас может быть успешное сканирование, которое затем не сможет сохранить его полное значение в битовом поле.

Учитывая дальнейшие комментарии, отмечающие, что вы не можете использовать шаг tmp, что совершенно неразумно для того, кто бы ни ставил эту задачу, вы не можете использовать scanf вообще. Однако вы можете прочитать строку отдельно, а затем использовать strtoul или аналогичный для преобразования числовых токенов в возвращаемые значения, которые могут быть непосредственно назначены в битовые поля. Я действительно не рекомендую это, но если это требование назначения или подобное, это возможно.

В соответствии с запросом: в разделе 7.21.6.1 раздела 7.21.6.1 спецификации C11 в параграфе 7 описаны модификаторы длины hh и h, используемые в этом примере. Они позволяют указывать длину целочисленного типа, где hh - это длина char, а h - это длина короткого. Комбинируя их с d i o u x или X, можно указать все встроенные целочисленные типы, которые будут считываться (f) scanf.

0 голосов
/ 12 января 2019

struct date определяется с использованием битовых полей и поэтому не выравнивается по границе байта. Поскольку он не находится на границе байтов, вы не можете получить его адрес с помощью оператора &. Попытка переопределить struct date следующим образом.

struct date {
    unsigned char day;
    unsigned char month;
    unsigned short year;
}

Это дает дополнительное преимущество: вы можете хранить годы до 65535 вместо 2047.

...