以相反的顺序读取输入

时间:2018-08-24 05:39:55

标签: c

我是C语言的新手。我刚刚学习了指针和struct。我正在尝试修改以下程序,以便将每个学生阅读的内容插入到学生列表的开头,而不是结尾。我该如何实现?

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

#define MAX_LINE_LENGTH 80      // The longest line this program will accept
#define MAX_NUM_STUDENTS 500    // The maximum number of students this program can handle
#define MAX_NAME_SIZE 50        // The maximum allowable name length
typedef struct student_s Student;

struct student_s {
    char name[MAX_NAME_SIZE];
    int age;
    Student* next;              // Pointer to next student in a list
};
Student studentPool[MAX_NUM_STUDENTS];  // The student pool
int firstFree = 0;
Student* newStudent(const char* name, int age)
{
    Student* student = NULL;
    if (firstFree < MAX_NUM_STUDENTS) {
        student = &studentPool[firstFree];
        firstFree += 1;
        strncpy(student->name, name, MAX_NAME_SIZE);
        student->name[MAX_NAME_SIZE - 1] = '\0';  // Make sure it's terminated
        student->age = age;
        student->next = NULL;
    }
    return student;
}
Student* readOneStudent(FILE* file)
{
    char buffer[MAX_LINE_LENGTH];  // Buffer into which we read a line from stdin
    Student* student = NULL;       // Pointer to a student record from the pool

    // Read a line, extract name and age

    char* inputLine = fgets(buffer, MAX_LINE_LENGTH, file);
    if (inputLine != NULL) {        // Proceed only if we read something
        char* commaPos = strchr(buffer, ',');
        if (commaPos != NULL) {
            int age = atoi(commaPos + 1);
            *commaPos = '\0';  // null-terminate the name
            student = newStudent(buffer, age);
        }
    }
    return student;
}
Student* readStudents(FILE *file)
{
    Student* first = NULL;     // Pointer to the first student in the list
    Student* last = NULL;      // Pointer to the last student in the list
    Student* student = readOneStudent(file);
    while (student != NULL) {
        if (first == NULL) {
            first = last = student;   // Empty list case
        } else {
            last->next = student;
            last = student;
        }
        student = readOneStudent(file);
    }
    return first;
}
void printOneStudent(Student student)
{
    printf("%s (%d)\n", student.name, student.age);
}
void printStudents(const Student* student)
{
    while (student != NULL) {
        printOneStudent(*student);
        student = student->next;
    }
}
int main(void)
{
    FILE* inputFile = fopen("studlist.txt", "r");
    if (inputFile == NULL) {
        fprintf(stderr, "File not found\n");
    } else {
        Student* studentList = readStudents(inputFile);
        printStudents(studentList);
    }
}

1 个答案:

答案 0 :(得分:4)

您当前有以下代码可插入(非空列表的)末尾:

if (first == NULL) {
    first = last = student;   // Empty list case
} else {
    last->next = student;
    last = student;
}

要在非空列表的前面插入,只需将新学生的next指针指向当前first学生,就可以使新学生成为第一位学生,并使first指针指向新学生。

if (first == NULL) {
    first = last = student;   // Empty list case
} else {
    student->next = first;
    first = student;
}

画框;用箭头连接它们。它应该变得显而易见。


此外,您可以简单地使用:

student->next = first;
first = student;

如果first为null,则student->next将被(重置)为null,因此在first上不需要特殊情况。由于last仅在函数中用于添加到列表的末尾,因此在最前面插入时根本不需要last。这两个发现使代码仍比第一个建议的版本简单。