-1

I want to create a C program to create a doubly linked list of character arrays. The input would be given like in a menu, with particular conditions for adding an element, breaking away etc. Initially I am only accepting the character input 'V' to create the list, otherwise the program breaks off.

But when I enter 'V' as the input (for the first time) and then a character array the else statement (inside the while loop) also gets executed which should be impossible. Can someone explain why this is happening? It may have some obvious mistake that I just cannot see.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>



struct website
{
    char web[30];
    struct website* forward;
    struct website* backward;
};


struct website* create(char* val, struct website* back) {
    struct website* curr = (struct website*)malloc(sizeof(struct website));
    if (curr) curr->forward = NULL;
    if (curr) curr->backward = back;
    if (curr) strcpy(curr->web, val);
    return curr;
}

int main() {

    struct website* websites = NULL;
    while (1) {

        char x;
        scanf("%c", &x);

        if (x == 'V') {

            char y[30];
            scanf("%29s", y);
            websites = create(y, websites);
        }
        else {
            printf("yes");
            break;
        }
    }
    printf(" bye ");
    return 0;
}
Nimish
  • 5
  • 3
  • I suggest that you run your program line by line in a [debugger](https://stackoverflow.com/q/25385173/12149471). You will probably notice that in the first loop iteration, `scanf` writes `'V'` into `x`, but in the second loop iteration, it writes `'\n'` into `x`. See the duplicate question for the reason why this happens. – Andreas Wenzel Feb 14 '22 at 14:38
  • 2
    The simple solution is to use `" %c"` with a leading space. The correct solution is to stop using `scanf`. – William Pursell Feb 14 '22 at 14:40
  • To clarify the previous comment: For line-based user input, it is usually better to read one line at a time using [`fgets`](https://en.cppreference.com/w/c/io/fgets), instead of partially reading lines using `scanf`. As you can see, a partially read line can easily cause problems. – Andreas Wenzel Feb 14 '22 at 14:43
  • Get into the habits of a) always checking scanf return value (won't help here, but still is a good habit) b) if you have input and something goes weird, echo your input and check that you see what you expect (if you'd echo the single characters you would notice what is going on) c) echo potentially white space input (i.e. ALL input) with separators like "", "" – Yunnosch Feb 14 '22 at 14:44
  • @Nimish Pay attention to that the function create as it is written does not make a sense. – Vlad from Moscow Feb 14 '22 at 14:45
  • Thanks @Andreas Wenzel and William Pursell. That was indeed the case and its working correctly now. – Nimish Feb 14 '22 at 14:45
  • Thanks for the feedback @Yunnosch and Vlad from Moscow – Nimish Feb 14 '22 at 14:48

1 Answers1

0

When the program has read the string there is still a newline character in the input buffer. When that newline character is then read the else clause is entered. The solution is to scan the first non-whitespace character by adding a space to the format string:

scanf(" %c", &x);

See also https://pubs.opengroup.org/onlinepubs/9699919799/

A directive composed of one or more white-space characters shall be executed by reading input until no more valid input can be read, or up to the first byte which is not a white-space character, which remains unread.

August Karlstrom
  • 10,773
  • 7
  • 38
  • 60