C语言程序get_data函数中continue_function调用失效问题求助
嘿,我瞅见你遇到的问题啦——程序在get_data循环里走到调用continue_function就直接终止了对吧?咱们来一步步揪出问题根源:
1. 直接导致崩溃的致命错误:continue_function里的getc用错了
你写的这段代码:
getc(ch);
完全不符合getc的用法!getc需要接收一个FILE*类型的参数(比如stdin代表标准输入),而且它的返回值才是读取到的字符。正确的写法应该是:
ch = getc(stdin);
你之前的写法会把ch的当前值当成内存地址传给getc,这直接触发了非法内存访问,程序可不就直接崩了嘛😅
2. 另一个隐藏的崩溃隐患:读取年份时的scanf参数错误
在get_data里读取生日年份的代码:
scanf("%d", list[last_entry].year);
这里少了取地址符&!scanf需要变量的内存地址才能把输入的值写进去,正确的写法是:
scanf("%d", &list[last_entry].year);
这个错误同样会导致非法内存写入,说不定在输入年份的时候就已经给程序埋下崩溃的种子了。
3. 其他需要修正的问题(避免后续奇怪行为)
(1)换掉废弃的gets函数
gets已经被C标准彻底废弃了,它不检查输入长度,很容易导致缓冲区溢出,严重的话会触发安全问题。建议换成fgets,比如读取名字的时候:
fgets(list[last_entry].fname, sizeof(list[last_entry].fname), stdin); // 注意:fgets会把换行符也读进去,得手动去掉 list[last_entry].fname[strcspn(list[last_entry].fname, "\n")] = '\0';
你的clear_kb函数用gets(junk)也有同样的溢出风险,改成更安全的写法:
void clear_kb(void) { int c; while ((c = getc(stdin)) != '\n' && c != EOF); }
这个写法会一直读取缓冲区里的字符,直到读完换行符或者遇到输入结束,完全不会溢出。
(2)main函数要符合标准
标准C要求main函数返回int类型,所以应该写成:
int main() { // ... 你的原有代码 ... return 0; }
(3)处理输入缓冲区的残留换行符
用scanf读取数字之后,输入缓冲区里会留下一个换行符,这会导致后续的fgets(或者原来的gets)直接读取到空行。你已经有clear_kb函数,记得在每次scanf读取完数字之后调用它清空缓冲区,比如在读取收入、生日的月/日/年之后都要调用。
修复后的continue_function示例
int continue_function(void) { char ch; printf("\n\nDo you wish to continue? (Y)es/(N)o: "); ch = getc(stdin); clear_kb(); // 清空缓冲区里的换行符 while(ch != 'n' && ch != 'N' && ch != 'y' && ch != 'Y') { printf("\n%c is invalid!", ch); printf("\n\nPlease enter 'N' to Quit or 'Y' to Continue: "); ch = getc(stdin); clear_kb(); } system("cls"); return (ch == 'n' || ch == 'N') ? NO : YES; }
把这些错误都修复之后,程序应该就能正常调用continue_function,不会再莫名其妙终止啦~
内容的提问来源于stack exchange,提问作者Charl_y

