Проблема зацикливания в C - PullRequest
3 голосов
/ 03 мая 2011

Я пишу простую программу на c, чтобы лучше понимать язык, но у меня странная проблема.Как вы видите из кода ниже, у меня есть только один цикл, который он завершает, когда я вставляю 255 в качестве значения.Проблема в том, что когда я выбираю первое (опция вставки) и после того, как я вставляю имя, программа запускает что-то вроде цикла и выдает мне все время экран выбора ...

#include<stdio.h>
#include<stdlib.h>
struct student{
    char *name;
    int id;
    };
void insertStudent(void);
struct student * init(void);    

int main(){
    struct student *p;
    int selectionCode=0;

    while(selectionCode!=255){
        printf("\nInsert students:1");
        printf("\nDisplay students:2");
        printf("\nExit:255");
        printf("\n\nEnter selection:");
        scanf("%d",&selectionCode);

        p=init();

        switch(selectionCode){
            case 1:
            insertStudent();
            //printf("1\n");
            break;
            case 2:
            //printf("2\n");
            break;
            case 255:
            break;
            }
        }

    //p->name="stelios";
    //p->id=0;
    //printf("Name:%s ID:%d",p->name,p->id);
    //free(p);
    //p=NULL;

    return 0;
}
struct student *init(void)
{
    struct student *p;
    p=(struct student *)malloc(sizeof(struct student));
    return p;
}
void insertStudent(void){
    struct student *p;
    p=init();
    printf("Enter Name:");
    scanf("%s",p->name);//return 1;
    printf("Enter ID:");
    scanf("%d",&p->id); 
    //printf("test");
    }

Ответы [ 6 ]

2 голосов
/ 03 мая 2011

Частично проблема может заключаться в том, что код не выделяет память для поля name в структуре.Функция init выделяет новую структуру, но не инициализирует поле name.Функция insertStudent затем использует scanf для считывания этого неинициализированного указателя.Это приводит к записи в «случайную» память и может привести к любому количеству проблем, включая нарушение доступа.

0 голосов
/ 03 мая 2011

Какой беспорядок ... :-) Вы никогда не используете malloc () буфер для p-> name, но вы заполняете его с помощью scanf ().Это портит память вашей программы.Кроме того ... В ваших функциях вы используете переменную p и в своей основной программе.Это НЕ та же самая переменная, но вы, кажется, предполагаете, что это так.Еще одна проблема: вернуть 1;после того как scanf () прерывает функцию insertStudent (), поэтому «ввод идентификатора» никогда не выполняется.Это пустая функция, поэтому она не должна возвращать значение, кстати.Вероятно, компилятор выдал предупреждение об этом.

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

0 голосов
/ 03 мая 2011

попробуйте:

struct student *insertStudent(void){
struct student *p;
p=init();
printf("Enter Name:");
scanf("%s",p->name);
printf("Enter ID:");
scanf("%d",&p->id); 
//printf("test");
 return p;
}

На главной

 case 1:
free(p);
    p=insertStudent();
    //printf("1\n");  

На инициале вы должны выделить место для имени.

0 голосов
/ 03 мая 2011

У вас есть «возврат 1;» после сканирования по названию. Похоже, по логике вы не должны возвращаться в этот момент, так как вы хотите ввести в ID. Кроме того, вы объявили функцию как возвращающую «void», поэтому возвращение одной из них является ошибкой.

Edit: реальная проблема в том, что вы никогда не выделяли место для строки имени.

0 голосов
/ 03 мая 2011

Вам необходимо убрать «return 1»; из insertStudent, иначе не будет компилироваться.

Вы должны инициализировать p-> name с помощью malloc и изменить "scanf ("% s ", p-> name);" на "scanf ("% s ", & p-> name);", потому что вам нужен указатель на * char.

0 голосов
/ 03 мая 2011

Похоже, у вас утечка памяти, я бы передал p в insertStudent ().

У вас также есть return 1; в середине вызова insertStudent (), поэтому он будет возвращаться до завершения своей работы.

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