0

Here is my code:

#include <stdio.h>
#include <stdlib.h>
enum abcd{aaaa,bbbb,cccc,dddd,z};

typedef struct stct{
    abcd eAbcd;
    int x;
} stct;
typedef struct indexx{
    int size;
    struct stct *addr;
} indexx;

void add_item(indexx *idx);
stct read_in();

int main()
{
    indexx idx = {0, NULL};
    int op;
    while (1)
    {
        printf("\n1. add item\n4. quit\n");
        scanf("%d\n", &op);
        switch (op)
        {
            case 1:
                add_item(&idx);
                break;
            case 4:
                return 0;
            default:
                printf("Please enter a correct number\n");
        }
    }
}

void add_item(indexx *idx)
{
    stct *newdata;
    newdata = (stct *) realloc(idx->addr, idx->size*sizeof(stct));
    if (newdata)
    {
        idx->size ++;
        idx->addr = newdata;
        idx->addr[idx->size-1] = read_in();
    }
    else
        printf("No memory\n");
}

stct read_in()
{
    stct temp;
    int ab;
    temp.eAbcd = z;
    while (temp.eAbcd != aaaa && temp.eAbcd != bbbb && temp.eAbcd != cccc && temp.eAbcd != dddd)
    {
        printf("select(1-4):\n");
        scanf("%d", &ab);
        ab-=1;
        switch (ab)
        {
            case 0: temp.eAbcd = aaaa; break;
            case 1: temp.eAbcd = bbbb; break;
            case 2: temp.eAbcd = cccc; break;
            case 3: temp.eAbcd = dddd; break;
        }
    }
    scanf("%d", &temp.x);
    return temp;
}

It was supposed to print out select(1-4): before scanf(), but when I compile and run the program, I got this:

1
select(1-4):

(1is what I entered.)

I have tried the solutions in C/C++ printf() before scanf() issue and none of them works for me.

Paradox
  • 19
  • 3
  • 1
    So you added for example `fflush()` like adviced there? –  Aug 06 '17 at 05:42
  • 1
    Where are you running this one ? – SRIDHARAN Aug 06 '17 at 05:42
  • 1
    @Sridharan running on fedora 26, compile using g++ 7.1.1 – Paradox Aug 06 '17 at 05:44
  • @FelixPalmen yes, I have tried all solutions from the answers to that question – Paradox Aug 06 '17 at 05:45
  • I think Sridharan's question was more about whether you **run** this in a standard terminal ... or maybe inside some IDE. –  Aug 06 '17 at 05:47
  • @FelixPalmen bash 4.4.12, directly run the complied file – Paradox Aug 06 '17 at 05:49
  • 3
    Well, can't reproduce (and I'm pretty sure nobody else can). Maybe you don't show **all** your code. Turning this into a [mcve] by adding `#include ` and a `main` function works as expected. –  Aug 06 '17 at 05:52
  • Can't reproduce, what I would do was to fiddle with termios commands and getchar to see what going on –  Aug 06 '17 at 06:05
  • @FelixPalmen I have put up the codes – Paradox Aug 06 '17 at 06:22
  • @Sridharan I have put up the codes – Paradox Aug 06 '17 at 06:22
  • Post your **full** input and **full** output of the program – n. m. could be an AI Aug 06 '17 at 07:15
  • I still can't see how you get the effect you describe, but the code is definitely broken, your `while` loops will not work as expected when you enter something that can't be parsed as a number by `scanf()`. For those `scanf()` related problems, you might want to read my [beginners' guide away from `scanf()`](http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html). Side note: `scanf()` treats all whitespace the same and `\n` **is** a whitespace, so if you meant to require a newline in the input -> it doesn't do that, it matches any sequence of whitespace. –  Aug 06 '17 at 07:15
  • @FelixPalmen this is part of my assignment, and we were only taught to use scanf to input. – Paradox Aug 06 '17 at 07:20
  • @Paradox this is unfortunate, because it's close to impossible to provide reliable interactive input with `scanf()`. The least you should do is check the return value of `scanf()` and just exit your program with an error if it doesn't return `1` when you expect exactly one conversion (like with `"%d"`). Btw, this code doesn't compile: `error: unknown type name ‘abcd’`. Are you accidentally using a C++ compiler to compile this? –  Aug 06 '17 at 07:27
  • @FelixPalmen yes I am using g++ to compile – Paradox Aug 06 '17 at 07:31
  • @Paradox don't. If it is C code, use a C compiler. C and C++ are quite different, although they have a common subset. Here you have **invalid** C code that *happens* to be valid C++ code. Change `enum abcd{aaaa,bbbb,cccc,dddd,z};` to `typedef enum abcd{aaaa,bbbb,cccc,dddd,z} abcd;` to make this valid C. As for your bug, I'm writing an answer explaining it. –  Aug 06 '17 at 07:32
  • @FelixPalmen Ok, I'll fix it, thank you very much – Paradox Aug 06 '17 at 07:34
  • @FelixPalmen Technically, any two languages have a common subset. – n. m. could be an AI Aug 06 '17 at 19:54

1 Answers1

1

Your problem is in this line:

    scanf("%d\n", &op);

The \n here is just a whitespace character (like and \t) and scanf() treats any whitespace character the same: They match a sequence of whitespace in the input stream of any length (including 0).

If you enter a number and hit enter, you do enter a newline and this newline is indeed matched by \n, it would also be matched by or \t. But you don't want to match it: stdin is by default line buffered, and as scanf() would optionally match more whitespace characters, it will wait for more input to see whether more whitespace is following and only return once you hit enter again because with line buffering, input only becomes available at a newline.

In a nutshell: This scanf() won't complete until you hit enter again, so add_item() isn't even called until you do.

The simple solution here: remove the bogus \n from the format string.