-1

I have done this countless times before and for some reason now I cannot seem to scanf a string in C. Here is my code for the specific function:

int putIn(NODE **head,NODE **current,NODE **prev) {
    char tempName[40];
    printf("Enter party name: ");

    scanf("%s",tempName);
    printf("Good?");
    current=head;
    int match=0;
    printf("Hi");
    while (*current !=NULL) {
        printf("No");   
        if (strcmp((*current)->name,tempName)==0) {
            printf("Name exists already");
            match=1;
            *current=(*current)->next;
        }
    }
    printf("HI");

The function does not even get to the printf("Good"); statement. thanks for your help!

Edit: Here is all code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define NODE struct node
struct node {
char name[20];
int number;
NODE *next;
};
int counter;

int putIn(NODE **head,NODE **current,NODE **prev);
int delete(NODE **head,NODE **current,NODE **prev);
int show(NODE **head,NODE **current,NODE **prev);
NODE *head=NULL;
NODE *current=NULL;
NODE *prev=NULL;
char tempName[40];
int main() {
int whileLoop=0;



while(whileLoop==0) {
    printf("Enter A Command: (1)Insert Party (2)Delete Party (3)Show List (4)Quit: ");
    int selection;
    scanf("%d",&selection);

    switch(selection) {
        case 1:
            putIn(&head,&current,&prev);
            break;
        case 2:
            delete(&head,&current,&prev);
            break;
        case 3:
            show(&head,&current,&prev);
            break;
        case 4:
            whileLoop=1;
            break;
        default:
            putIn(&head,&current,&prev);
    }
}
return 0;
}
int putIn(NODE **head,NODE **current,NODE **prev) {
//char tempName[40];
printf("Enter party name: ");

scanf("%s",tempName);

printf("Good?");
current=head;
int match=0;
printf("Hi");
while (*current !=NULL) {
    printf("No");   
    if (strcmp((*current)->name,tempName)==0) {
        printf("Name exists already");
        match=1;
        *current=(*current)->next;
    }
}
printf("HI");
current=(NODE **)malloc(sizeof(NODE *));
if (*head==NULL) {
    head=current;
}
(*current)->next=NULL;
strcpy((*current)->name,tempName);
printf("enter party size: ");
scanf("%d",&(*current)->number);

prev=head;
int i;
for (i=0;i<counter-1;i++){
    *prev=(*prev)->next;
}
if (counter!=0) {
(*prev)->next=*current;
}
printf("%d",(*head)->number);
counter+=1;
return 0;
}
int delete(NODE **head,NODE **current,NODE **prev) {
int openTable;
printf("Enter open table size: ");
scanf("%d",&openTable);
current=head;
int match=0;
int grow=0;
while (*current!=NULL) {
    if ((*current)->number<=openTable) {
        match=1;
        printf("A table of %d has been removed",(*current)->number);
        prev=head;
        int i;
        for (i=0;i<grow-1;i++) {
            *prev=(*prev)->next;
        }
        (*prev)->next=(*current)->next;
        free(*current);
        counter-=1;
    } else {
        grow+=1;
        *current=(*current)->next;
    }
}
return 0;
}
int show(NODE **head,NODE **current,NODE **prev) {
if (head==NULL) {
    printf("\nNo data entered");
}
else {
    printf("\nHere is the waiting list: \n");
}
current=head;
while (*current !=NULL) {
    printf("Name: %s Size: %d\n",(*current)->name,(*current)->number);
    *current=(*current)->next;
}
return 0;
}
rubber boots
  • 14,018
  • 5
  • 31
  • 44
Ian Richard
  • 505
  • 4
  • 9
  • 3
    What are you typing in? – Grice Oct 22 '14 at 18:25
  • 4
    Use a debugger. Since you aren't including a newline in the `printf("Good");` call, the fact that you aren't seeing output does not mean it isn't executing. The output may be buffered, and the crash may be later. – nobody Oct 22 '14 at 18:26
  • 3
    IO is buffered. If your program crashes, there may be stuff in the output buffer that never makes it to the console even though the code executed. Better break out your debugger. – Nicu Stiurca Oct 22 '14 at 18:26
  • 3
    The most important question is: how are the arguments `NODE **head, NODE **current, NODE **prev` initialized before they go into `putIn`? – rubber boots Oct 22 '14 at 18:26
  • `scanf("%s", ...)` reads a single whitespace-delimited word of arbitrary length. If you type more than will fit in the 40 bytes you've allocated, bad things may happen. Which is why we can't help without knowing what input you provided. Also, change `printf("Good?");` to `printf("Good?\n"); fflush(stdout);` to make sure the output actually appears; you may be executing that line but not seeing its output. You should change `"%s"` to something that specifies a maximum length. – Keith Thompson Oct 22 '14 at 18:27
  • As @AndrewMedico said, try including `\n` in your function. – Piotr Zierhoffer Oct 22 '14 at 18:27
  • @Andrew Are you sure a newline in the printf would flush the buffer? I know a `std::endl` flushes an `std::ostream`, but I'm not knowledgable enough about `printf` to know if it has a similar mechanism. – Nicu Stiurca Oct 22 '14 at 18:29
  • http://stackoverflow.com/questions/1716296/why-does-printf-not-flush-after-the-call-unless-a-newline-is-in-the-format-strin – nobody Oct 22 '14 at 18:30
  • The NODES are all initialized with: – Ian Richard Oct 22 '14 at 18:30
  • NODE *head=NULL; NODE *current=NULL; NODE *prev=NULL; – Ian Richard Oct 22 '14 at 18:31
  • Passed into function with : putIn(&head,&current,&prev); – Ian Richard Oct 22 '14 at 18:32
  • `*current=(*current)->next;` -->> `current = &(*current)->next;` – wildplasser Oct 22 '14 at 18:32
  • 2
    **There is no point in passing a variable to a function if you immediately set it to some other value!** You might as well just declare it locally in that function. For example, you pass `NODE **current`, but you immediately set `current=head`. You might as well declare `NODE **current=head`. The reason I have emphasized this, is that although it is not a direct answer to your question, it is most likely where the problem stems from (your misunderstanding of how pointers are used in order to pass information in and out of a function). – barak manos Oct 22 '14 at 18:37

1 Answers1

0

The problem has nothing to do with scanf if you don't enter something too long. Your candidates for crash are:

  while (*current != NULL) {

and

  if (strcmp((*current)->name, tempName) == 0) {

depending on the initialization status of your pointers to pointers, one of these might lead to segfault.

You have to provide the context of the function call where you call putIn(...);

Edit: After you gave insight into your logic, here's the error:

You start out with:

NODE *head = NULL;
NODE *current = NULL;
NODE *prev = NULL;

and, without any further initialization, go into:

putIn(&head, &current, &prev);

where you do the following:

 ...
 current = (NODE **)malloc(sizeof(NODE *));
 ...

which means, the actual parameter (an important address value, that has been copied on the stack) in the function call is overwritten by the malloc result (which can't be correct, maybe you meant *current = (NODE *) malloc(sizeof(NODE)); ... or sth. else).

In the next step, you initialize (disconnect too) head with the already-disconnected current:

 if (*head == NULL) {
     head = current;
 }

In the next line, you dereference the allocated pointer and access it as it would point to a structure node (with a NODE* member), which has not been allocated so far ...

(*current)->next = NULL;

which segfaults (because *current does not point to an allocated structure node).

rubber boots
  • 14,018
  • 5
  • 31
  • 44
  • 1
    `scanf` is **definitely** a "candidate for crash". It has no idea that the buffer has room for only 40 `char`s, and will happily overflow it if the user types in more than 40 characters. – nobody Oct 22 '14 at 18:31
  • @AndrewMedico yes, but it has low probability that the user enters more than 39 characters on the first try ;) The problem w/pointers seems to have a much higher probability. – rubber boots Oct 22 '14 at 18:32
  • True, I saw your answer before you edited to adjust the wording. – nobody Oct 22 '14 at 18:41
  • Thank you, rubber boots, I was able to get rid of the seg fault. – Ian Richard Oct 22 '14 at 19:51