Формат "% s" ожидает аргумент типа "* char", но аргумент 2 имеет тип "int" - PullRequest
0 голосов
/ 24 октября 2018

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

#include <stdio.h>

struct students {
    char name[20];
    int score[20];
} student;
int main() {
int i, n;
    printf("Number of students:\n");
    scanf("%d", &n);
    for(i=0; i<n; i++) {
        printf("Name of the student:\n");
        scanf("%s", &student.name[i]);
        printf("Score of the student:\n");
        scanf("%d", &student.score[i]);
    }
for(i=0;i<n;i++) {
    if(student.score[i] >= 15) {
        printf("%s passed the exam\n", student.name[i]); }
    else {
        printf("%s failed the exam\n", student.name[i]);
    }
    }
return 0;
}

Ответы [ 5 ]

0 голосов
/ 24 октября 2018

scanf("%s", &student.name[i]); Вы обращаетесь к единственной char из строки, которую вы объявили.Я предполагаю, что вы хотели бы индивидуальный объект для каждого студента.Для этого я бы посоветовал определить ваш struct следующим образом:

typedef struct students {
    char name[20];
    int score;
}Student;

С этим вы определили новый тип данных с именем Student.Каждый объект типа Student имеет строку с именем name и int, напоминающую счет.

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

Student student1, student2;

В качестве альтернативы, вы можете создать массив Student s: Student group[20], а затем запустите цикл с данными:

for(int i = 0; i < n; i++){
        puts("Name of the student: ");
        fgets(group[i].name, 20, stdin);
        puts("Score of the student: ");
        scanf("%d", &group[i].score);
}

Сделка на одну итерацию для ссылки на отдельный объект массива студентов.Кроме того, я настоятельно рекомендую использовать fgets() или как минимум gets_s() для ввода строк.scanf() имеет несколько проблем, некоторые из которых заключаются в том, что он останавливает ввод, если встречает пробел, табуляцию или символ новой строки, и, что наиболее важно, он не проверяет границы массива.Рассмотрите возможность использования более безопасного варианта, просто имейте в виду, что fgets() добавляет '\n' перед завершающим нулем.

0 голосов
/ 24 октября 2018

Имя студента является единственным массивом символов и должно быть массивом символьных массивов.

struct students {
    char name[20][40];
    int score[20];
} student;

Я произвольно предположил, что 40 символов на имя было достаточно.

Scanf дляимя необходимо изменить с:

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

На:

scanf("%s", student.name[i]);
0 голосов
/ 24 октября 2018

Ваш код имеет довольно много проблем.1) студент должен быть массивом (или динамически распределяемой памятью).2) сканирование строки должно быть выполнено в виде

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

или

scanf("%s", &student[i].name[0])

3) Тем не менее, у вас возникнет проблема, если строкадлина пересекает 20 байт (включая нулевой символ).

0 голосов
/ 24 октября 2018
char name[20];

выделяет пробел для одиночной 20-символьной строки, поэтому students.name[i] относится к одному символу (который повышается до типа int в вызове scanf).

Чтобы определить массив строк , вам нужен двумерный массив char, например

char name[NUMBER_OF_STRINGS][MAX_STRING_LENGTH+1];

, и вы читаете его как

scanf( “%s”, student.name[i] ); // no & operator here

Выражения массива «затухают» в выражении указателя в большинстве случаев, поэтому вам здесь не нужен оператор &.

В качестве альтернативы, вы можете объявить массив указателей на char, например,

char *name[NUMBER_OF_STRINGS];

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

char buffer[MAX_STRING_LENGTH+1];
...
scanf( “%s”, buffer );
student.name[i] = malloc( strlen( buffer ) + 1 );
if ( student.name[i] )
  strcpy( student.name[i], buffer );

Вам просто нужно помнить free каждый student.name[i], когда вы закончите.

0 голосов
/ 24 октября 2018

Существует несколько проблем:

printf("%s passed the exam\n", student.name[i]);

student.name[i] - это char, но спецификатор формата %s хочет указатель на char.

Но реальная проблемав том, что ваша декларация студентов не то, что вам нужно.Следующая структура объявляет одного студента, чье имя может быть длиной до 19 символов и иметь 20 баллов.

struct students {
    char name[20];
    int score[20];
} student;

Но вам нужно 20 (или больше?) Студентов, каждый из которых имеет один балл:

struct student {
  char name[50];    // name up to 49 characters
  int score;        // score
} student;

struct student students[20];  // array of 20 students

Или оставьте реализацию кода читателю в качестве упражнения.Вам необходимо ознакомиться со следующими понятиями:

  • массивы
  • структуры
  • строки
  • основы scanf и printf

Все эти темы описаны в вашем учебнике по Си.

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