为什么此 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);