C语言学分绩点计算程序添加姓名输出后异常,如何正常显示姓名?
问题分析与修复方案
你的程序提前终止的核心原因是内存越界访问,具体问题出在这几个关键点:
- 你将
name(姓名)、mk(课程名)声明为单个char类型,但使用scanf("%s", ...)读取字符串——单个char仅能存储1个字符,而%s会把输入的完整字符串(包括末尾的\0终止符)全部写入,直接超出变量内存范围,破坏程序栈结构,导致崩溃或提前退出。 - 读取成绩字母
nh时,错误使用%s格式符,同样会对单个char变量造成内存溢出。
修复步骤
- 将存储字符串的变量改为字符数组,比如
char name[50], mk[50];(长度可按需调整,50足够覆盖普通姓名和课程名)。 - 单个字符类型的
nh,读取时改用%c格式符,同时在格式符前加空格" %c",跳过输入缓冲区残留的空白字符(如换行)。 - 推荐用
fgets代替scanf("%s")读取姓名和课程名,支持带空格的输入(比如"Maria Silva"这类姓名),更符合实际使用场景。 - 计算绩点
rt时,强制将sum转为float类型,避免整数除法导致结果被截断。
完整修复代码
#include <stdio.h> int main(){ int i, N, kodemk, sks, b, sum, sumsksb, jsks; char mk[50], nh, name[50]; // 修改为字符数组存储字符串 float rt; printf("Jumlah mata kuliah "); scanf("%d", &N); getchar(); // 清除scanf留下的换行符 printf("Your Name "); fgets(name, sizeof(name), stdin); // 去掉fgets读取的末尾换行符 for(int k=0; name[k]!='\0'; k++){ if(name[k]=='\n'){ name[k]='\0'; break; } } sum=0; jsks = 0; for(i=1; i<=N; i++){ printf ("Masukkan kode mata kuliah "); scanf("%d", &kodemk); getchar(); // 清除换行符 printf("Masukkan Nama mata kuliah "); fgets(mk, sizeof(mk), stdin); // 去掉课程名的换行符 for(int k=0; mk[k]!='\0'; k++){ if(mk[k]=='\n'){ mk[k]='\0'; break; } } printf("Masukkan jumlah sks "); scanf("%d", &sks); printf("Masukkan Nilai Huruf mata kuliah "); scanf(" %c", &nh); // 用%c读取单个字符,空格跳过空白 if(nh == 'A') b = 4; else if(nh == 'B') b = 3; else if(nh == 'C') b = 2; else if(nh == 'D') b = 1; else if(nh == 'E') b = 0; sumsksb = sks * b; sum += sumsksb; jsks += sks; } rt = (float)sum / jsks; // 强制类型转换避免整数除法 printf("\nNama:\n%s\n", name); printf("IP %.2f\n", rt); return 0; }
内容的提问来源于stack exchange,提问作者Maulana
相关产品推荐
相关产品推荐

