предупреждение: формат '% s' ожидает аргумент типа 'char *', но аргумент 2 имеет тип 'char (*) [30]' [-Wformat =] - PullRequest
0 голосов
/ 07 мая 2019

Я создаю базу данных со студентами, я создал struct Students

struct Students {
    //struct specific for students
    char first_name[30];
    char last_name[30];
    int ssn;
};

void add_student() {
    //function to add students
    int i, n;
    struct Students *student;
    printf("How many students are you adding");
    scanf("%d", &n);

    student = (struct Students *)malloc(n * sizeof(struct Students *)); //allocate the memory for n students

    for (i = 0; i < n; i++) {
        printf("Enter first, last and ssn respectively");
        scanf(" %s ", &(student+i)->first_name); //adds first name to student i
        scanf(" %s ", &(student+i)->last_name);// adds last name to student i
        scanf(" %d ", &(student+i)->ssn); //adds ssn to student i
    }

    for (i = 0; i < n; i++) {
        //print each of the students being added
        printf("First name: %s\n ", (student+i)->first_name);
        printf("Last name: %s\n ", (student+i)->last_name);
        printf("ssn: %d\n ", (student+i)->ssn);
    }
    free(student); //free the memory used 
}

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

Фактические данные:

warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[30]’ [-Wformat=]
    scanf(" %s ", &(student+i)->first_name);

Ответы [ 2 ]

2 голосов
/ 07 мая 2019

Просто передайте массив в качестве аргумента, который превратится в указатель на его первый элемент:

scanf("%s", student[i].first_name);

Вы передаете адрес массива, который имеет то же значение, но не имееттот же тип, что и адрес первого элемента.Компилятор обнаруживает это несоответствие типов как выдачу предупреждения (что является очень хорошей вещью!)

Вот список других проблем в вашем коде:

  • Вы должны проверить возвращаемое значение scanf(), чтобы обнаружить неверный или отсутствующий ввод.
  • Также добавьте тесты достоверности для значений, введенных с помощью scanf().
  • Память, выделенная для массиваStudents неверно: вы выделяете n время размера указателя, вы должны выделять n время размера самого Student struct.
  • Удалите конечные пробелы в scanf()формат строкиЭто приводит к тому, что дополнительный ввод читается без причины.
  • Также добавьте максимальное количество символов для хранения в целевые массивы: "%29s".
  • Проверьте значения возврата scanf() дляобнаружить пропущенный ввод.

Вот исправленная версия:

struct Students {
    //struct specific for students
    char first_name[30];
    char last_name[30];
    int ssn;
};

void add_student() {
    //function to add students
    int i, n;
    struct Students *student;

    printf("How many students are you adding");
    if (scanf("%d", &n) != 1 || n <= 0) {
        printf("invalid input\n");
        return 1;
    }

    // Allocate the memory for n students
    student = malloc(n * sizeof(struct Students));

    for (i = 0; i < n; i++) {
        printf("Enter first, last and ssn respectively: ");
        if (scanf("%s", student[i].first_name) != 1
        ||  scanf("%s", student[i].last_name) != 1
        ||  scanf("%d", student[i].ssn) != 1) {
            printf("invalid input or missing input\n");
            n = i; // only `i` students have ben read
            break;
        }
    }

    for (i = 0; i < n; i++) {
        // print each of the students being added
        printf("First name: %s\n", student[i].first_name);
        printf("Last name: %s\n", student[i].last_name);
        printf("ssn: %d\n", student[i].ssn);
    }
    free(student); //free the memory used 
}
1 голос
/ 07 мая 2019
warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 
has type ‘char (*)[30]’ [-Wformat=]

Это предупреждение отображается, потому что вы используете & при сканировании (student+i)->first_name и (student+i)->last_name. Вам не нужно ставить & перед именем переменной при сканировании string . Обратите внимание, что & необходимо использовать перед всеми другими типами переменных.

Измените это на строку:

scanf(" %s ", &(student+i)->first_name);
scanf(" %s ", &(student+i)->last_name);

К

scanf(" %s ", (student+i)->first_name);
scanf(" %s ", (student+i)->last_name);

И предупреждение исчезнет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...