如果我使用GPA指针和scanf("%lf",& GPA),为什么在使用scanf("%lf",GPA)时会出现分段错误它不是指针?

时间:2017-03-22 15:20:27

标签: c double scanf

void fillQueueWithStudents(Queue *q)
{
  int counter = 1;
  char answer = 'Y';

  //this signifies the current variables that
  //are being dealt with
  char *currName;
  double GPA;

  student stud;
  while((answer != 'N') || (answer != 'n'))
  {
    printf("Please enter the info for student %i \n",counter);

    //Gets the name of the current student being entered
    printf("Name: ");
    scanf("%s", currName);
    printf("\n");

    //Gets the gpa of the current student being entered
    printf("GPA: ");
    scanf("%lf", &GPA); 
    //somewhere here is the problem
    printf("\n");

    //makes our student have the current variables
    stud.name = currName;
    stud.gpa = GPA;

    //enqueues this student
    enQueue(q,stud);

    //increments to the next student
    counter++;

    //This sees if the user wants to enter another student
    printf("Do you want to enter another student. Enter 'N' or 'n' for 
     no. \n");
    scanf("%c", &answer);
    printf("\n");
  }
}

我在scanf之前和之后打印了你好,他们都打印了。它不允许我输入GPA的值。我想知道它是否正在扫描整个换行符或类似的东西。我不明白为什么它不会让我投入一个价值。我猜它是在试图把太多的东西放到GPA变量中。

以下是完整的程序。

#include <stdlib.h>
#include <stdio.h>

typedef struct
{
  char *name;
  float gpa;
}student;

//This struct will represent a node in the queue
typedef struct Node
{
  student *stud;
  struct Node *next;
}QNode;

//This struct will identify the queue
//It will store the front and rear values to make
//it easier to enqueue and dequeue
typedef struct
{
  QNode *front, *rear;
}Queue;

/*
This creates a new node with some data k.
It then sets its next value to NULL.
Then it returns the new node

Note: This node is not yet known to the queue. I will
use a separate function to do that
*/
QNode* newNode (student *stud)
{
  QNode *temp = (QNode*)malloc(sizeof(QNode*));
  temp->stud->gpa = stud->gpa;
  temp->stud->name = stud->name;
  temp->next = NULL;
  return temp;
}

//Creats a empty queue
Queue* createQueue()
{
  Queue *q = (Queue*)malloc(sizeof(Queue*));
  q->front = q->rear = NULL;
  return q;
}
/*
Uses the newNode function to make a new node in our linked list.
Then it puts that node in the correct place in the queue. This
is at the back
*/
void enQueue(Queue *q, student stud)
{
  QNode *temp = newNode(&stud);//this creats a new node

  /*
  Checks if queue is empty, and if it is sets
  our new node temp to rear and front. Then it
  ends the function
  */
  if(q->rear == NULL)
  {
    q->front = q->rear = temp;
    return;
  }
  //sets the current rears next to our new node temp
  q->rear->next = temp;
  //this makes temp the new rear
  q->rear = temp;
}

/*
This function serves/dequeues a node.
As always nodes are dequeued from the front of the
queue
*/

QNode *deQueue(Queue *q)
{
  //if the queue is empty tell the user by
  //returning NULL
  if(q->rear == NULL)
  {
    return NULL;
  }

  /*
  I will return front to the user in case they want
  to use the data included in it. I have to save
  front first to do that. So I save it hear
  */
  QNode *temp = q->front;

  //Now I make front equal to its next
  q->front = q->front->next;

  /*
  This makes rear NULL if front is NULL
  This means the list is empty and we have dequeued the last
  node.
  */
  if(q->front == NULL)
  {
    q->rear == NULL;
  }

  printf("The element dequeued was %s \n",temp->stud->name);
  //This returns the node we have dequeued
  return temp;
}

void printQueue(Queue *q)
{
  //Check is the queue is empty and if it is stop the
  //function
  if(q->rear == NULL)
  {
    return;
  }

  /*
  I will now print out each node out one by one.
  To do this I create a QNode pointer and make it equal to the
  front. I will then print all contents of front
  and make temp equal to the next print and repeat this
  till the end.
  */
  QNode *temp = q->front;
  while(temp != NULL)
  {
    int counter = 1;
    printf("Student %i:      Name: %s          GPA: %f \n",
     counter, temp->stud->name, temp->stud->gpa);

    //increment the counter to display next student
    counter++;

    //Get the next node
    temp = temp->next;
  }
}

/*
This function keeps adding students to the queue until the
user enters 'N' that signifies they are done
*/
void fillQueueWithStudents(Queue *q)
{
  int counter = 1;
  char answer = 'Y';

  //this signifies the current variables that
  //are being dealt with
  char *currName;
  float GPA;

  student stud;
  while((answer != 'N') || (answer != 'n'))
  {
    printf("Please enter the info for student %i \n",counter);

    //Gets the name of the current student being entered
    printf("Name: ");
    scanf("%s", currName);
    printf("\n");

    //Gets the gpa of the current student being entered
    printf("GPA: ");
    scanf("%f", &GPA);
    printf("\n");

    //makes our student have the current variables
    stud.name = currName;
    stud.gpa = GPA;

    //enqueues this student
    enQueue(q,stud);

    //increments to the next student
    counter++;

    //This sees if the user wants to enter another student
    printf("Do you want to enter another student. Enter 'N' or 'n' for no. \n");
    scanf("%c", &answer);
    printf("\n");
  }
}

int main()
{
  Queue *q = createQueue();

  fillQueueWithStudents(q);

  QNode *temp;
  do {
    temp = deQueue(q);
    free(temp);
    printQueue(q);
  } while(temp != NULL);

  return 0;
}

1 个答案:

答案 0 :(得分:0)

此:

scanf("%s", currName);

是未定义的行为,因为currName未初始化。使用scanf()和普通%s来读取名称并不是一个好主意。使用缓冲区(!)然后告诉scanf()缓冲区大小:

char currName[128];

if(scanf("%127s", currName) == 1)
{
}

...并检查返回值,如图所示。

请注意%s在第一个空白字符处停止,因此您无法读取包含空格的名称。