C: ошибка при вызове структуры функции в main - PullRequest
0 голосов
/ 14 октября 2018

Есть ли у вас идеи, почему scanf в alegereStudent не работает?Консоль позволяет мне писать случайные вещи в пустых строках и показывает случайные числа после printf.Я пытаюсь сделать проект для начинающих, но я не знаю, почему эта структура не позволяет мне делать scanf так, как я хочу.

Код:

#include<stdio.h>

struct student
{
    char numeStudent[20];
    char prenumeStudent[20];
    int idStudent;
    float medieAdmitere;
};

struct profesor
{
    char *numeProfesor[20];
    char *prenumeProfesor[20];
    char *domeniu[20];
};

void alegereStudent( struct student stud){
    printf("Introduceti Numele: %s", stud.numeStudent);
    scanf("%s\n",&stud.numeStudent);
    printf("Introduceti Prenumele:%s",stud.prenumeStudent);
    scanf("%s\n",&stud.prenumeStudent);
    printf("Introduceti ID-ul studentului:%d",stud.idStudent);
    scanf("%d\n",&stud.idStudent);
    printf("Introduceti Media de admitere:%f",stud.medieAdmitere);
    scanf("%f\n",&stud.medieAdmitere);
};

int main(void)
{
    int intrDate=0,cautDate=0,listDate=0,iesire=0,desprStudenti=0,desprProfesori=0,inapoi=0;
    struct student stud;
    printf("Meniu principal:\n\n");
    printf("1.Introducere date. %d\n",intrDate);
    printf("2.Cautare date.%d\n",cautDate);
    printf("3.Listare date.%d\n",listDate);
    printf("0.Iesire Aplicatie.%d\n",iesire);
    printf("Alegeti o optiune:");
    scanf("%d,%d,%d,%d",&intrDate,&cautDate,&listDate,&iesire);
    if(intrDate==1){
        printf("1. Despre studenti %d\n",desprStudenti);
        printf("2. Despre profesori\n");
        printf("3. Revenire la meniul principal\n");
        printf("Alegeti o optiune:");
        scanf("%d",&desprStudenti);
    }
    if(desprStudenti==1)
        alegereStudent(stud);

    return 0;
}

Ответы [ 2 ]

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

Код в alegereStudent() изменяет локальную переменную stud, но это просто копия неинициализированной структуры, созданной в main() - она ​​не влияет на структуру, находящуюся в main().

Чтобы функция изменила структуру в вызывающей функции, необходимо передать указатель на структуру.Ссылки на члены структуры затем используют оператор стрелки -> вместо оператора точка ..Вы не хотите распечатывать старые (неинициализированные) значения;Вы хотите запросить новое значение.И вы не хотите передавать char (*)[20] (указатель на массив из 20 символов), где функция scanf() ожидает простое char * - удаление & из строк.

Один мажорпроблема в том, что вам НЕ нужен завершающий символ новой строки в строках scanf() .Это означает, что пользователь должен вводить символ без пробелов, чтобы остановить ввод, и люди не умеют предсказывать, что будет необходимо дальше.Во всех конверсиях, которые вы используете, пропускаются первые пробелы, включая переводы строк, поэтому вам не нужно беспокоиться о оставленной после них новой строке (или, если вы хотите беспокоиться об этом, вы не делаете это с \n в строке формата scanf()).

void alegereStudent(struct student *stud)
{
    printf("Introduceti Numele: ");
    scanf("%19s", stud->numeStudent);
    printf("Introduceti Prenumele: ");
    scanf("%19s", stud.prenumeStudent);
    printf("Introduceti ID-ul studentului: ");
    scanf("%d", &stud.idStudent);
    printf("Introduceti Media de admitere: ");
    scanf("%f", &stud.medieAdmitere);
}

Эти форматы ограничивают строки 19 символами плюс нулевой байт, поэтому вы не получите переполнения, но они не гарантируют, что вы читаете (и выбросить?) лишние байты.Помните: %s читает до следующего пробела.Если пользователь вводит Robin Hood в первой строке, первая scanf() будет читать Robin, а следующая Hood (без ожидания новых данных, введенных пользователем.

Обратите также внимание, что точка с запятойпосле того, как функция не требуется. Она отмечает конец пустого объявления (переменной?) после тела функции.

Вам, конечно, нужно изменить вызов в функции main():

if (desprStudenti == 1)
    alegereStudent(&stud);

И лучше не помещать семь определений переменных в одну строку. Действительно, обычно лучше использовать одну строку на переменную. И использовать больше пробелов.

int intrDate=0,cautDate=0,listDate=0,iesire=0,desprStudenti=0,desprProfesori=0,inapoi=0;

int intrDate = 0;
int cautDate = 0;
int listDate = 0;
int iesire = 0;
int desprStudenti = 0;
int desprProfesori = 0;
int inapoi = 0;

При создании MCVE ( Минимальный, Полный, Проверяемый пример ) лучше всего удалить неиспользуемые переменные и ввестиопределения и исключения меню (просто вызовите код, который необходимо выполнить) и т. д.

См. также Руководство для начинающих вдали от scanf(). Функция scanf() является одной изсамые сложные функции для правильного использования.Это легко, но когда все становится сложнее, scanf(), вероятно, не тот инструмент для работы.

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

Scanf ERROR: Вам необходимо удалить & из scanf в alegereStudent функции, чтобы прочитать stud.numeStudent и stud.prenumeStudent - вам нужно узнать о массивах и указателях.Кроме того, вам нужно включить <stdio.h> и поставить ; после return 0.

Причина ошибки: массив распадается на указатель, а scanf нужен указатель для чтения пользовательского ввода в переменные, следовательно, нетнужно поставить &.

Предложение: http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html

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