C语言基础例题1-3题-指针篇
C语言基础例题4-5题-二维数组篇
C语言基础例题6-7题-结构体篇
编写一个学生成绩管理系统,实现以下功能:
编写一个程序,要求用户输入一个字符串,然后计算该字符串的长度,并输出结果。
测试用例
输入:“Hello” 输出:长度为5
输入:“This is a test” 输出:长度为14
输入:“1234567890” 输出:长度为10
输入:" " 输出:长度为1
输入:“” 输出:长度为0
输入:“Special characters: *&^%$#@!” 输出:长度为28
#include
#include
#include
// 定义学生信息结构体
typedef struct
{
char name[20];
int score;
} Student;
// 定义链表节点结构体
typedef struct Node
{
Student data;
struct Node *next;
} Node;
// 在链表末尾添加新节点(学生信息)
void addStudent(Node *head)
{
Node *p = head;
while (p->next != NULL)
{
p = p->next;
}
Node *newNode = (Node *)malloc(sizeof(Node));
printf("请输入学生姓名:");
scanf("%s", newNode->data.name);
printf("请输入成绩:");
scanf("%d", &(newNode->data.score));
newNode->next = NULL;
p->next = newNode;
printf("添加成功!\n");
}
// 根据学生姓名删除节点
void deleteStudent(Node *head)
{
char name[20];
printf("请输入要删除的学生姓名:");
scanf("%s", name);
Node *p = head->next;
Node *prev = head;
while (p != NULL)
{
if (strcmp(p->data.name, name) == 0)
{ // 学生姓名匹配,删除节点
prev->next = p->next;
free(p);
printf("删除成功!\n");
return;
}
prev = p;
p = p->next;
}
printf("查无此人!\n");
}
// 根据学生姓名查找学生信息
void findStudent(Node *head)
{
char name[20];
printf("请输入要查询的学生姓名:");
scanf("%s", name);
Node *p = head->next;
while (p != NULL)
{
if (strcmp(p->data.name, name) == 0)
{ // 学生姓名匹配,显示学生信息
printf("姓名:%s\t成绩:%d\n", p->data.name, p->data.score);
return;
}
p = p->next;
}
printf("查无此人!\n");
}
// 根据学生姓名修改学生成绩
void modifyScore(Node *head)
{
char name[20];
int newScore;
printf("请输入要修改成绩的学生姓名:");
scanf("%s", name);
printf("请输入新的成绩:");
scanf("%d", &newScore);
Node *p = head->next;
while (p != NULL)
{
if (strcmp(p->data.name, name) == 0)
{ // 学生姓名匹配,修改成绩
p->data.score = newScore;
printf("修改成功!\n");
return;
}
p = p->next;
}
printf("查无此人!\n");
}
// 显示所有学生信息
void displayStudents(Node *head)
{
Node *p = head->next;
while (p != NULL)
{
printf("姓名:%s\t成绩:%d\n", p->data.name, p->data.score);
p = p->next;
}
}
int main()
{
Node *head = (Node *)malloc(sizeof(Node));
head->next = NULL;
int option;
do
{
printf("【菜单】\n");
printf("1. 添加学生信息\n");
printf("2. 删除学生信息\n");
printf("3. 查找学生信息\n");
printf("4. 修改学生成绩\n");
printf("5. 显示所有学生信息\n");
printf("6. 退出程序\n");
printf("\n请选择菜单选项:");
scanf("%d", &option);
switch (option)
{
case 1:
addStudent(head);
break;
case 2:
deleteStudent(head);
break;
case 3:
findStudent(head);
break;
case 4:
modifyScore(head);
break;
case 5:
displayStudents(head);
break;
case 6:
printf("程序结束!\n");
break;
default:
printf("错误!没有此选项!\n");
break;
}
} while (option != 6);
// 释放链表内存
Node *p = head;
while (p != NULL)
{
Node *temp = p->next;
free(p);
p = temp;
}
return 0;
}
struct _StudentItem:定义了学生信息的结构体。它包含一个char数组name用于存储学生姓名,一个int变量score用于存储成绩。
struct Node:定义了链表节点的结构体。它包含了一个Student类型的数据成员data用于存储学生信息,以及一个指向下一个节点的指针next。
addStudent:在链表末尾添加新节点(学生信息)。该函数首先遍历链表,找到最后一个节点,然后创建一个新节点,要求用户输入学生的姓名和成绩,并将新节点添加到链表末尾。
deleteStudent:根据学生姓名删除节点。该函数要求用户输入要删除的学生姓名,然后从链表头开始遍历每个节点,寻找匹配的学生姓名。如果找到匹配的节点,则删除该节点,并释放内存。如果没有找到匹配的节点,输出"查无此人!"。
findStudent:根据学生姓名查找学生信息。该函数要求用户输入要查询的学生姓名,然后从链表头开始遍历每个节点,寻找匹配的学生姓名。如果找到匹配的节点,则输出该学生的姓名和成绩。如果没有找到匹配的节点,输出"查无此人!"。
modifyScore:根据学生姓名修改学生成绩。该函数要求用户输入要修改成绩的学生姓名和新的成绩,然后从链表头开始遍历每个节点,寻找匹配的学生姓名。如果找到匹配的节点,则修改该节点的成绩为新的成绩。如果没有找到匹配的节点,输出"查无此人!"。
displayStudents:显示所有学生信息。该函数从链表头开始遍历每个节点,并输出每个节点的学生姓名和成绩。
在主函数里,我们首先创建了一个链表头指针head,然后使用一个菜单循环,等待用户输入菜单选项。根据用户的选择,调用相应的函数执行相应的功能。直到用户选择退出程序为止。最后,释放了链表的内存。
相比起答案2,这个的链表位置是添加在最后的,每次都要遍历一次,这一步可以优化。
#include
#include
#include
// 定义学生信息结构体
typedef struct _StudentItem
{
char name[9];
float grade;
} StudentItem;
// 定义链表节点结构体
typedef struct _StudentNode
{
StudentItem item;
struct _StudentNode *next;
} StudentNode;
// 在链表开头添加新节点(学生信息)
void AddStudent(StudentNode **student);
// 根据学生姓名删除节点
void DeleteStudent(StudentNode **student, char *name);
// 根据学生姓名修改学生成绩
void ModifyGrades(StudentNode *student, float grade);
// 显示所有学生信息
void displayStudents(StudentNode **student);
// 根据学生姓名查找学生信息
StudentNode *FindStudent(StudentNode **student, char *name);
// 释放链表内存
void FreeNode(StudentNode **student);
int main(void)
{
StudentNode *student = NULL, *target;
int selection;
char name[9];
float grade;
printf("【菜单】\n1.添加学生信息\n2.删除学生信息\n3.查找学生信息\n4.修改学生成绩\n5.显示所有学生信息\n6.退出程序\n");
while (scanf("%d", &selection) == 1 && selection != 6)
{
switch (selection)
{
case 1:
AddStudent(&student);
break;
case 2:
printf("请输入要删除的学生名:");
scanf("%s", name);
DeleteStudent(&student, name);
break;
case 3:
printf("请输入要查询的学生名:");
scanf("%s", name);
target = FindStudent(&student, name);
if (target == NULL)
printf("查无此人!\n");
else
printf("姓名:%s\t成绩:%f\n", target->item.name, target->item.grade);
break;
case 4:
printf("请输入要修改成绩的学生名:");
scanf("%s", name);
target = FindStudent(&student, name);
if (target == NULL)
printf("查无此人!\n");
else
{
printf("请输入新的成绩:");
scanf("%f", &grade);
ModifyGrades(target, grade);
puts("修改成功");
}
break;
case 5:
displayStudents(&student);
break;
default:
printf("错误!没有此选项!\n");
break;
}
printf("继续输入选项:\n");
}
FreeNode(&student);
getchar();
getchar();
return 0;
}
void AddStudent(StudentNode **student)
{
StudentNode *temp = (StudentNode *)malloc(sizeof(StudentNode));
printf("请输入学生姓名:");
scanf("%s", temp->item.name);
printf("请输入成绩:");
scanf("%f", &temp->item.grade);
temp->next = *student;
*student = temp;
}
void DeleteStudent(StudentNode **student, char *name)
{
StudentNode *target = *student, *prev;
// 学生姓名匹配,删除节点
if (target != NULL && !strcmp(target->item.name, name))
{
*student = target->next;
}
else
{
prev = target;
target = target->next;
while (target != NULL)
{
// 学生姓名匹配,删除节点
if (!strcmp(target->item.name, name))
{
prev->next = target->next;
break;
}
prev = target;
target = target->next;
}
}
if (target != NULL)
{
free(target);
printf("删除成功!\n");
}
else
{
printf("删除失败!\n");
}
}
void ModifyGrades(StudentNode *student, float grade)
{
student->item.grade = grade;
}
StudentNode *FindStudent(StudentNode **student, char *name)
{
StudentNode *p = *student;
while (p != NULL)
{
// 学生姓名匹配,返回学生节点
if (!strcmp(p->item.name, name))
break;
p = p->next;
}
return p;
}
void displayStudents(StudentNode **student)
{
const StudentNode *p = *student;
if (*student == NULL)
{
printf("没有学生数据\n");
}
else
{
while (p != NULL)
{
printf("姓名:%s\t成绩%f\n", p->item.name, p->item.grade);
p = p->next;
}
}
}
void FreeNode(StudentNode **student)
{
StudentNode *target=*student,*next;
while(target!=NULL)
{
next=target->next;
free(target);
target=next;
}
}
我们使用链表来存储学生的信息,也就是姓名和成绩。根据题目要求需要实现添加学生、删除学生、查找学生、修改学生的成绩、显示所有学生的信息,退出的功能。
首先,我们定义了两个结构体:StudentItem 和 StudentNode。StudentItem 用来存储学生的姓名和成绩,而 StudentNode 用来表示链表中的节点,它包含一个 StudentItem 类型的变量和一个指向下一个节点的指针。
然后,我们实现一些函数来完成不同的操作。AddStudent 函数用于在链表开头添加一个新的学生节点;DeleteStudent 函数用于根据学生的姓名来删除对应的节点;ModifyGrades 函数根据学生的姓名来修改他们的成绩;displayStudents 函数显示所有学生的信息;FindStudent 函数根据学生的姓名来查找他们的信息;最后,FreeNode 函数用来释放链表的内存。
在主函数中,我们通过一个循环来让用户选择要执行的操作。根据用户的输入,我们会调用相应的函数来处理操作。比如,如果用户选择添加学生,我们会创建一个新的节点,然后获取学生的姓名和成绩,最后将其添加到链表的开头。
如果要删除学生,我们先根据学生的姓名找到对应的节点,然后将其从链表中删除并释放其内存。修改学生的成绩,先根据学生的姓名找到对应的节点,然后更改他的成绩。显示所有学生的信息,就遍历链表并打印每个学生的姓名和成绩。
在程序结束时,记得释放链表的内存。
相比答案1,这个链表的开头只使用了一个指针,没有一个空的结构体,所以省了一个结构体的空间,嗯,没什么用。而且造成添加等操作会多出几行代码来。
另外就是链表的添加顺序了,这个是添加在开头,速度很快,答案一添加之前还要找到末尾,较慢。
#include
int main(void)
{
int sum = 0;
while (getchar() != '\n')
sum++;
printf("长度为%d\n", sum);
getchar();
return 0;
}
首先定义一个整型变量sum并初始化为0。然后使用一个while循环来读取用户输入的字符,每读取一个字符,就将sum的值加1,直到遇到换行符\n为止。这样就可以统计出用户输入的字符个数。
接着使用printf函数打印出统计得到的字符长度。
这个方法比下面两个简单,但是缺点是从缓冲区独走字符后,全部都删掉了,没有保存下来用户输入的字符串。
#include
#include
int main(void)
{
char str[50];
int i = 0;
printf("请输入:");
while ((str[i] = getchar()) != '\n')
i++;
str[i] = '\0'; // 添加字符串结束符
printf("长度为%d\n", strlen(str));
getchar();
return 0;
}
char str[50]; 声明一个字符数组 str,用于存储用户输入的字符串,最大长度为 50。
int i = 0; 声明一个整型变量 i,用于循环和计数。
while ((str[i] = getchar()) != ‘\n’)。这个循环的作用是逐个字符读取用户输入并存储到 str 中,直到遇到换行符 \n 为止。
i++; 每次循环结束后将变量 i 自增,用于确保存储下一个字符的位置。
printf(“长度为%d\n”, strlen(str)); 输出字符串的长度,使用了 strlen 函数来计算字符串的长度。
比答案1要多几个步骤,而且此处直接延伸答案1的算法,不去使用strlen也可以。
#include
#include
int main()
{
char str[100];
printf("请输入一个字符串: ");
fgets(str, 100, stdin);
// 去掉输入字符串的换行符
str[strcspn(str, "\n")] = 0;
int length = strlen(str);
printf("输入字符串的长度为: %d\n", length);
return 0;
}
char str[100]; 声明一个字符数组 str,用于存储用户输入的字符串,最大长度为 100。
fgets(str, 100, stdin); 使用 fgets 函数从标准输入流 stdin 中获取用户输入的字符串,最多读取 99 个字符(包括空字符),并存储到 str 中。
str[strcspn(str, “\n”)] = 0; 使用 strcspn 函数找到 str 中换行符 \n 的位置,并将其替换为字符串结束符 \0,从而去掉字符串结尾的换行符。
int length = strlen(str); 使用 strlen 函数计算字符串 str 的长度,并将结果存储在 length 变量中。
printf(“输入字符串的长度为: %d\n”, length); 输出字符串的长度。
比前两个看着额,至少这道题不是在学fgets和strcspn之前出现的,所以老师看了都会夸你。