1

I am implementing a polynomial using array. This is the Problem Statement:

Write a menu-driven program to represent Polynomials as a data structure using arrays. and write functions to add, subtract and multiply two polynomials; multiply a polynomial with a constant, find whether a polynomial is a "zero- polynomial, return the degree of the polynomial. Assume that a new polynomial is created after each operation. How would you input and output polynomials?

I have created the input and output functions. But my do while loop is running twice.. Help me finding out why.

The do-while loop

do{
        print_menu();

        scanf("%c",&ch);
        printf("\nch = %c\n",ch);
    switch(ch){
        case '1':
            create_poly(poly,termpool,&next_poly);
            break;
        case '2':
            print_poly(poly,termpool,&next_poly);
            break;
        case 'q':
            break;
        default:
            printf("Invalid choice.");
    }
}while(ch != 'q');

return 0;

}

The print_menu() function

void print_menu()
{
    printf("\n1. Create a new polynomial.");
    printf("\n2. Print polynomial.");
    printf("\nq. Exit");
    printf("\nEnter Choice:");
}

The create_poly() function

void create_poly(int poly[][2], int termpool[][2], int *next_poly)
{
    int beg = poly[*next_poly][0];
    int end, size, i, j;

    printf("Enter size of the polynomial:");
    scanf("%d",&size);
    poly[*next_poly][1] = beg + size - 1;
    end = poly[*next_poly][1];

    printf("Enter terms of the polynomial(coeff then exponent):\n");
    for(i=beg; i<=end; i++){
        for(j=0; j<2; j++){
            scanf("%d ",&termpool[i][j]);
        }
    }

    poly[++(*next_poly)][0] = end + 1;
}

The print_poly() function

void print_poly(int poly[][2],int termpool[][2],int *next_poly)
{
    int pos,beg,end;
    int i;

    printf("Enter position of the polynomial:");
    scanf("%d",&pos);
    if(pos-1 > *next_poly){
        printf("Invalid position.");
        return;
    }

    beg = poly[pos-1][0];
    end = poly[pos-1][1];
    for(i=beg; i<=end; i++){
        printf(" %dx^%d +",termpool[i][0],termpool[i][1]);
    }
    printf("\b = 0");

}

Here is a sample output:

1. Create a new polynomial.
2. Print polynomial.
q. Exit
Enter Choice:1

ch = 1
Enter size of the polynomial:2
Enter terms of the polynomial(coeff then exponent):
2 4
6 7

1. Create a new polynomial.
2. Print polynomial.
q. Exit
Enter Choice:
ch = 

Invalid choice.
1. Create a new polynomial.
2. Print polynomial.
q. Exit
Enter Choice:q

ch = q

Tried flushing the stdin… The problem stays. Printing the value of ch in each step, I think it is a whitespace. Where does the white space comes?


The answer to abnormal behavior of scanf answers this question also.
Community
  • 1
  • 1
SouvikMaji
  • 1,088
  • 3
  • 22
  • 39
  • 3
    You should read the documentation of every function that you are using, notably [scanf(3)](http://man7.org/linux/man-pages/man3/scanf.3.html). You should test the result of `scanf`. You should compile with all warnings & debug info (`gcc -Wall -Wextra -g`). And you should learn how to **use the debugger** (`gdb`). Also, edit your question to improve it. It is missing a `Linux` tag! – Basile Starynkevitch Nov 05 '14 at 16:41
  • And please put `\n` at end, not start, of [printf(3)](http://man7.org/linux/man-pages/man3/printf.3.html) format strings. See also [fflush(3)](http://man7.org/linux/man-pages/man3/fflush.3.html) – Basile Starynkevitch Nov 05 '14 at 16:43
  • 2
    @BasileStarynkevitch: I disagree with the tag-suggestion. If it should be portable (no indication it should not), the linux-tag would be wrong. – Deduplicator Nov 05 '14 at 16:43
  • As @BasileStarynkevitch eluded, adding `fflush(stdout);` after printing the prompts will help with the output. – ash Nov 05 '14 at 16:45
  • 2
    I think you'll find [**this question**](http://stackoverflow.com/questions/19337351/abnormal-behavior-of-scanf) informative, btw. – WhozCraig Nov 05 '14 at 16:49
  • Just add a printf of the ch you're switching on inside the loop while likely help locate your problem. – D'Nabre Nov 05 '14 at 16:52
  • 1
    this line: scanf("%d",&pos); has two problems 1) the return value from scanf() needs to be check to assure the target parameters are actually input/set. 2) a scanf() does not consume white space without specific coding in the format parameter. suggest the format parameter be: " %d" so leading white space be consumed, including any newline character(s) – user3629249 Nov 05 '14 at 19:05
  • I have rarely seen a scanf problem that couldn't be fixed by looking at its return value. Surprise: scanf tells you something important in the return value. Why do you ignore it? – Jens Nov 05 '14 at 19:42
  • @user3629249: All conversions but `c` and `[` consume initial white-space; `"%d"` and `" %d"` are equivalent format strings. – mafso Nov 06 '14 at 18:01

2 Answers2

0

There's an extra character waiting to be consumed after you make your initial choice, that's why the loop is executing twice.

See this question on the comp.lang.c FAQ

FractalDoctor
  • 2,496
  • 23
  • 32
0

If you test the next code you will note the same problem

int main() {
    char c;

    do {
        scanf_s("%c", &c);
        if (c != 'q')
             printf("test scanf() function\n");

    } while (c);
}

the scanf() function works when the enter key is pressed, but this insert another char in the buffer input, the char of new line '\n', it is taken again by scanf() because the loop block. Try to change the previous code by this code:`

do {
    scanf_s("%c", &c); // or c = getchar();
    switch (c){
    case '\n':
        break;
    default:
        printf("test scanf() function\n");
    }

} while (c);`

and will work fine. In your code only add a new case in the switch block:

 switch(ch) {
    case '1':
        create_poly(poly,termpool,&next_poly);
        break;
    case '2':
        print_poly(poly,termpool,&next_poly);
        break;

    case '\n':
        break;

    case 'q':
        break;
    default:
        printf("Invalid choice.");
 }

sorry, English is not my native language

Brent Faust
  • 9,103
  • 6
  • 53
  • 57