2017-04-03 106 views
0

我想創建一個學生的數據庫程序,您應該能夠添加/修改和刪除學生。我設法使add函數工作,並且修改函數,但刪除函數給我一些問題。我試圖從數據庫中刪除一個學生時,我的代碼似乎崩潰了,誰能告訴我問題在哪裏?動態數組結構,刪除元素

這裏是我的代碼:

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

/* TODO: Avoid global variables. */ 

struct student { 
    char name[60]; 
    long long personalNumber; 
    char gender[6]; 
    char studyProgram[60]; 
    char email[30]; 
    int age; 
}; 

struct student *pointer = NULL; 
int numberofstudents = 0; 

void modify() 
{ 
    long long persnr; 
    long long comp; 
    int match = 0; 
    printf("Please enter the personal number that you wish to modify: \n"); 
    scanf("%lld", &persnr); 
    getchar(); 

    for(int i = 0; i <= numberofstudents; i++) 
    { 
     comp = ((pointer+i)->personalNumber); 
     printf("%lld\n", ((pointer+i)->personalNumber)); 
     printf("%lld\n", comp); 


     printf("Inne"); 
     if (pointer[i].personalNumber == persnr && match == 0) 
     { 
      printf("Enter name, personalnumber, gender, studyprogram, email and age in this order\n"); 
      scanf("%s%lld%s%s%s%d", (pointer+i)->name, &(pointer+i)->personalNumber, (pointer+i)->gender, (pointer+i)->studyProgram, (pointer+i)->email, &(pointer+i)->age); 
      match = 1; 
      getchar(); 
     } 
     if (match == 0) 
     { 
      printf("Could not find person"); 
     } 

    } 
} 


void deletestudent() 
{ 
    long long persnr; 
    long long comp; 
    int match = 0; 
    printf("Please enter the personal number that you wish to delete: \n"); 
    scanf("%lld", &persnr); 
    getchar(); 

    struct student *temporary = malloc((numberofstudents - 1) * sizeof(struct student)); 

    for(int i = 0; i <= numberofstudents; i++) 
    { 
     if (pointer[i].personalNumber == persnr && match == 0) 
     { 
      match = 1; 
     } 
     else if (match == 1){ 
      temporary[i-1] = pointer[i]; 
     } 
     else 
     { 
      temporary[i] = pointer[i]; 
     } 

     if (match == 0) 
     { 
      printf("Could not find person"); 
     } 

    } 
    free(pointer); 
    pointer = temporary; 

    } 



void add(){ 

     if (numberofstudents > 0) 
     { 
      pointer = (struct student*) realloc(pointer, (numberofstudents+1) * sizeof(struct student)); 

      printf("Lyckades allokeringen!\n\n"); 
     } 

     printf("Enter name, personalnumber, gender, studyprogram, email and age in this order\n"); 
     scanf("%s%lld%s%s%s%d", (pointer+numberofstudents)->name, &(pointer+numberofstudents)->personalNumber, (pointer+numberofstudents)->gender, (pointer+numberofstudents)->studyProgram, (pointer+numberofstudents)->email, &(pointer+numberofstudents)->age); 
     getchar(); 
     printf("Visar data:\n"); 

     for(int i = 0; i <= numberofstudents; ++i) 
     { 
      printf("%s\t%lld\t%s\t%s\t%s\t%d\n", (pointer+i)->name, (pointer+i)->personalNumber, (pointer+i)->gender, (pointer+i)->studyProgram, (pointer+i)->email, (pointer+i)->age); 
     } 
     numberofstudents = numberofstudents+1; 
    } 

int main(void) 
{ 
    pointer = (struct student*) malloc(2 * sizeof(struct student)); 

    if (pointer == NULL) 
{ 
    printf("pointer NULL"); 
    exit(1); 
} 

    int run = 1; 
    int choice; 

    while (run == 1) 
    { 
     printf("Please enter an option listed below\n1.ADD\n2.Modify\n3.Delete\n4.Search\n5.Save\n6.Load\n7.Exit"); 
     scanf("%d", &choice); 
     getchar(); 

     switch(choice) { 

    case 1 : 
     add(); 
     break; 

    case 2 : 
     modify(); 
     break; 
    case 3 : 
     deletestudent(); 


    case 7 : 
     exit(0); 
     break; 

    default : 

     break; 
} 

    } 


    return 0; 
} 
+1

'numberofstudents'是數組中元素的數量,還是數組中的頂部索引?因爲如果它是第一個,那麼你所有的循環將會超越結尾,並且當你索引超出範圍時,你將會有*未定義的行爲。 –

+0

如果'deletestudent()'中的'persnr'不存在,你可以將'numberofstudents'元素複製到'temporary'(實際上,請參閱@some程序員夥計的評論),但該數組被賦予-1元素。你也永遠不會減少'numberofstudents' –

+0

如果你輸入超過五個字符的性別,比如「女性」,你將會遇到問題(未定義的行爲)。 (對於個人號碼使用整數類型是有問題的;它更多是一個數字字符序列(即數字),而不是實際的號碼。) – molbdnilo

回答

0

正如在評論中提到,這樣的:

for(int i = 0; i <= numberofstudents; i++) 

是一個巨大的警示標誌。在C中,假設numberofstudents是數組的實際長度,則此循環中通常應該有i < numberofstudents

使用<=而不是<會使循環過度一步,從而導致數組外部索引並導致未定義的行爲。

寫外部堆分配的內存,然後嘗試free()這是一個激發崩潰的好方法,因爲您有可能踩到堆分配器的數據結構(在實踐中,理論上所有發生的是你得到未定義的行爲,因此可能發生任何事情)。