为什么此 scanf 语句会导致分段错误?
Why is this scanf statement causing Segmentation Faults?
我已经用头撞墙一个小时了,我快疯了...我有一段代码(是的,这是作业)抛出分段错误,除非我注释掉我的 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: %d\n", 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("****-****-****-%s\n", 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
输入邮政编码被跳过,我在输入任何燃料等级后立即出现段错误。但是,如果我注释掉 scanf("%d", &gasGrade); 行代码 运行s 很好。
最初我没有初始化变量,我的代码组织也有点不同,但我似乎找不到解决这个问题的正确方法。 我做错了什么?
感谢您的帮助!
因为通过 scanf("%s", ccNumber);
和 ccNumber = NULL
你正在取消对 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
,并且您 必须 始终检查 [=15= 的 return 值] 以防止未定义的行为。
您要么必须使用 malloc
为 ccNumber 分配内存,要么将其定义为数组 char ccNumber[17]
(16 位数字 + \0 字符)。现在它是指向您初始化为 NULL
.
的单个字符的指针
您没有为 cc Number 分配内存(ccNumber 为 NULL)
读取数字时必须清除换行符,但要使用 scanf 读取另一个值,会自动读取输入缓冲区 (stdin) 中的 '\n'。
printf("Please Enter Your Billing Zip Code: ");
scanf("%d", &zip);
变化:
scanf("%d", &zip);
收件人:
scanf("%d%*c", &zip);
我已经用头撞墙一个小时了,我快疯了...我有一段代码(是的,这是作业)抛出分段错误,除非我注释掉我的 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: %d\n", 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("****-****-****-%s\n", 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
输入邮政编码被跳过,我在输入任何燃料等级后立即出现段错误。但是,如果我注释掉 scanf("%d", &gasGrade); 行代码 运行s 很好。
最初我没有初始化变量,我的代码组织也有点不同,但我似乎找不到解决这个问题的正确方法。 我做错了什么?
感谢您的帮助!
因为通过 scanf("%s", ccNumber);
和 ccNumber = NULL
你正在取消对 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
,并且您 必须 始终检查 [=15= 的 return 值] 以防止未定义的行为。
您要么必须使用 malloc
为 ccNumber 分配内存,要么将其定义为数组 char ccNumber[17]
(16 位数字 + \0 字符)。现在它是指向您初始化为 NULL
.
您没有为 cc Number 分配内存(ccNumber 为 NULL)
读取数字时必须清除换行符,但要使用 scanf 读取另一个值,会自动读取输入缓冲区 (stdin) 中的 '\n'。
printf("Please Enter Your Billing Zip Code: ");
scanf("%d", &zip);
变化:
scanf("%d", &zip);
收件人:
scanf("%d%*c", &zip);