我已经用头撞墙一个小时了,我疯了。。。我有一段代码(是的,这是家庭作业)会抛出分段错误,除非我注释掉我的一个scanf语句。我试着用gdb调试这个问题,但直到今天我还没有真正学到任何东西。
这是代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char * creditCard(char * ccNumber){
char * lastFour;
lastFour = (ccNumber + strlen(ccNumber) - 4);
return lastFour;
}
void zipCode(int zip){
printf("The zip code entered is: %dn", zip);
}
int fuelGrade(int grade){
}
int main(void){
char * ccNumber = NULL;
int zip = 0;
int gasGrade = 0;
printf("Please Enter Credit Card Number: ");
scanf("%s", ccNumber);
printf("Please Enter Your Billing Zip Code: ");
scanf("%d", &zip);
printf("Select your Fuel Grade.n Unleaded(1) Plus(2) Premium(3): ");
scanf("%d", &gasGrade);
ccNumber = creditCard(ccNumber);
printf("****-****-****-%sn", ccNumber);
zipCode(zip);
return 0;
}
当我按原样编译和运行时,我会得到以下内容:
Please Enter Credit Card Number: 123413515
Please Enter Your Billing Zip Code: Select your Fuel Grade.
Unleaded(1) Plus(2) Premium(3): 1
Segmentation fault
输入邮政编码被跳过,在输入任何燃油等级的内容后,我都会得到一个segfault。但是,如果我注释掉scanf("%d",&gasGrade)line代码运行良好。
最初我没有初始化变量,代码的组织也有点不同,但我似乎找不到解决这个问题的正确方法我做错了什么
谢谢你的帮助!
因为通过用ccNumber = NULL
执行scanf("%s", ccNumber);
,您正在取消引用NULL
指针。
scanf()
的"%s"
说明符需要一个指向有效内存的指针,它可以在其中写入扫描的数据,而您传递的是NULL
指针,它不检查指针是否为NULL
,因此它取消了对NULL
指针的引用。
你需要有效的内存,所以你可以在这种情况下使用堆栈,比如这个
char buffer[100];
char *ccNumber;
if (scanf("%99s", buffer) != 1)
problemScanning_buffer_DoNotUse_buffer_In_TheFollowingCode();
ccNumber = creaditCard(buffer);
请注意上面的99
,它可以防止buffer
溢出,并且您必须始终检查scanf()
的返回值,以防止"未定义的行为"。
您必须使用malloc
为ccNumber分配内存,或者将其定义为数组char ccNumber[17]
(16位+\0个字符)。现在,它是一个指针,指向您初始化为NULL
的单个字符。
您不为ccNumber(ccNumber为NULL)分配内存
读取数字时,必须清除换行符,但要使用scanf读取另一个值,请自动读取输入缓冲区(stdin)中的'\n'。
printf("Please Enter Your Billing Zip Code: ");
scanf("%d", &zip);
更改:
scanf("%d", &zip);
收件人:
scanf("%d%*c", &zip);