簡體   English   中英

C 字符串中的奇怪字符(結構、指針和字符串)

[英]Weird characters in string with C (Structs, pointers, and strings)

嗨,我正在創建一個包含學生信息的鏈接列表。

但是,當顯示 student 結構的字符串變量時,它顯示的字符不是它應該顯示的字符串。 這是我的代碼片段(我刪除了與我的問題無關的代碼):

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

struct Student {
    int student_number[2];
    char *last;
    char *first;
    char *course; 
    int year;
    int age;
    char sex; 
    int grade;
    struct Student * next;
};

typedef struct Student Student;

struct SLList {
    Student * head;
    Student * tail;
    int size;
};

typedef struct SLList SLList;

void initList(SLList * list){
    list->head = 0;
    list->tail = 0;
    list->size = 0;
}

Student * getStudent(SLList * list, int index) {
    Student * current = list->head;
    for (int i = 0; i < index; i ++) {
        current = current->next;
    }
    return current;
}

Student * createStudent(int * number, char *last, char *first, char * course, int year, int age, char sex, int grade){
    Student * student = (Student *) malloc(sizeof(Student));
    student->student_number[0] = number[0];
    student->student_number[1] = number[1];
    student->last = last;
    student->first = first;
    student->course = course;
    student->year = year;
    student->age = age;
    student->sex = sex;
    student->grade = grade;
    student->next = 0;

    return student;
}

void enrolStudent(SLList * list, int index){
    Student * student;
    int i, found = 1;
    int student_number[2];
    char last[15];
    char first[15];
    char course[15];
    int year;
    int age;
    char sex;
    int grade;

    printf("Student Number: ");
    scanf("%i-%i", &student_number[0], &student_number[1]);

    printf("Last Name: ");
    scanf("%s", last);

    printf("First Name: ");
    scanf("%s", first);

    printf("Course: ");
    scanf("%s", course);

    printf("Year: ");
    scanf("%i", &year);

    printf("Age: ");
    scanf("%i", &age);

    printf("Sex [M or F]: ");
    scanf(" %c", &sex);

    printf("Final Grade: ");
    scanf("%i", &grade);

    Student * toInsert = createStudent(student_number, last, first, course, year, age, sex, grade);

    if (index == 0){
        toInsert->next = list->head;
        list->head = toInsert;
    }
    if (index == list->size){
        if (list->tail != 0) {
            list->tail->next = toInsert;
        }
        list->tail = toInsert;
    }
    list->size ++;

    return;

}

void showStudents(SLList * list, int index) {
    Student * student = getStudent(list, index);

    printf("\n");
    printf("Student Number: %i-%i\n", student->student_number[0], student->student_number[1]);
    printf("Last Name: %s\n", student->last);
    printf("First Name: %s\n", student->first); //! error in printing strings 
    printf("Course: %s\n", student->course);
    printf("Year Level: %i\n", student->year);
    printf("Age: %i\n", student->age);
    printf("Sex: %c\n", student->sex);
    printf("Final Grade: %i\n", student->grade);
    printf("\n");
}


int main(){
    int choice = 0;
    int rtn = 0;

    SLList students;
    initList(&students);

    printf("What do you want to do?\n");
    printf("1. Enrol a student\n");
    [...]
    printf("4. Display all student/s\n");


    for(;;){
        printf("\nEnter a number: ");
        rtn = scanf("%d", &choice);

        if (choice == 1) {
            enrolStudent(&students, students.size);
        } else if (choice == 4) {
            int i;
            for (i = 0; i < students.size; i ++){
                showStudents(&students, i);
            }
            printf("Displaying %i of %i student(s)\n", i, students.size);
        }
        [...]
}

我相信我需要為結構的char *變量分配memory,但我不知道它應該如何go。

希望能得到一些幫助。 謝謝!

您將局部變量地址傳遞給createStudent並簡單地將其分配給錯誤的內部指針。

你可以做的是使用類似strdup調用的東西,如下所示

student->last = strdup(last);
student->first = strdup(first);
student->course = stddup(course);

或為lastfirstcourse分配空間並復制字符串

您的假設是正確的:您將指向堆棧對象的指針分配給列表元素。 因此,在進一步執行程序的過程中,內容很可能會被覆蓋,這會給您帶來 output 中的奇怪字符。

正確的方法是在createStudent期間為字符串分配 memory,這是通過malloc或最小字符串長度的calloc完成的。 你的 function 中已經有一個例子,所以我有點驚訝你說你不知道該怎么做。 另一種可能性是為此目的調用strdup ,它基本上完全結合了分配和字符串復制。

哦,還有一句話:請從你職業生涯的一開始就養成一種習慣,那就是你自己清理。 含義:無論你分配什么,在使用后釋放它。 在您的情況下:如果您有一個createStudent function,請創建一個destroyStudent function。 如果您在某處有一個鏈表,請在退出程序之前釋放它。 盡早養成這種習慣將使您免於在未來發生 memory 泄漏。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM