C: GCC bug or incorrect code?

Hi all,

I'm trying to write a program that will take some strings in as input, and merge them into one string to output. This program doesn't want to execute the last getchar() function through, and I can't figure out why.

Here is the code:

Code:
#include <stdio.h>

int get(char *x);
int gettype(void);
int fetchext(char *y);

main()
{
        int type, i, j;
        char one[16];
        char two[16];
        char three[6];

        for (i = 0; i < 16; i++)
                one[i] = 0;
        for (i = 0; i < 16; i++)
                two[i] = 0;
        for (i = 0; i < 6; i++)
                three[i] = 0;

        printf("Enter number: ");
        if (!get(&three[0])) {
                printf("Error\n");
        }
        printf("%s", &three[0]);

        type = gettype();

        printf("%s", &two[0]);

        printf("Enter Internal IP: ");
        if (!get(&two[0])) {
                printf("Error\n");
        }

        return 0;
}

int get(char *x)
{
        int i = 0;

        while ((x[i++]=getchar()) != '\n')
                putchar(x[i]);
        x[i] = '\0';
        return 1;
}

int gettype(void)
{
        int x = 0;

        while (x < 1 || x > 3) {
                printf("\none\t1\ntwo\t2\nthree\t3\n");
                printf("Select one: ");

                x = (getchar() - '0');
        }
        return x;
}

int fetchext(char *y)
{
        int i = 0;

        while ((y[i++]=getchar()) != '\n')
                ;
        y[i] = '\0';
        return 1;
}

Output:
Code:
%./a.out
Enter number: 1
1

one     1
two     2
three   3
Select one: 1
Enter Internal IP: %

The last call to 'get'
Code:
if (!get(&two[0])) {
would printf the text, but then gets returned to command prompt instead of waiting for user input. If I were to move the gettype() function before the first get() function however, the code would get fully executed.

Does anyone have any ideas to why this is happening? Any help would be appreciated.

Andy
 
Code:
while ((x[i++]=getchar()) != '\n')
        putchar(x[i]);
let's do this step by step. First, we evaluate getchar(), then we assign that value to x, then we compare x to '\n', then we increment i to i+1. If x (with i being the old value of it) was equal to linebreak, we jump to the end, otherwise we evaluate putchar(x).
I.e. the value passed to putchar is not the one you've read by getchar, but the one after it (since it was incremented after the getchar but before the putchar), which is 0 as it was set earlier in some for-loop.
 
xibo said:
Code:
while ((x[i++]=getchar()) != '\n')
        putchar(x[i]);
let's do this step by step. First, we evaluate getchar(), then we assign that value to x, then we compare x to '\n', then we increment i to i+1. If x (with i being the old value of it) was equal to linebreak, we jump to the end, otherwise we evaluate putchar(x).
I.e. the value passed to putchar is not the one you've read by getchar, but the one after it (since it was incremented after the getchar but before the putchar), which is 0 as it was set earlier in some for-loop.


You have actually stumbled upon (possibly) another mistake of mine - the putchar() shouldn't be in there. It was originally in for debug purposes and I never remembered to take it out because as you rightly saw it never put anything to output so didn't notice. This isn't the cause/nature of the bug though, and can be ignored.

However, the nature of my problem is that getchar() gets called, but I don't get the chance to enter text into x (see last line of output).

I installed gdb to step through, and the little I've learned to use it tells me that getchar does get called... but even in the debug I don't get a chance to input text; the code just runs straight through to the end and exits cleanly as far as I can tell.
 
andyzammy said:
However, the nature of my problem is that getchar() gets called, but I don't get the chance to enter text into x (see last line of output).

If you use <enter/return> for submitting your entries, then the function gettype() would leave a pending '\n' on stdin, which then would be immediately picked-up in the final call to get(), which therefore finishes prematurely.
 
rolfheinrich said:
If you use <enter/return> for submitting your entries, then the function gettype() would leave a pending '\n' on stdin, which then would be immediately picked-up in the final call to get(), which therefore finishes prematurely.

I think I get it.. gettype() only asks for one char, but the process of entering it in makes a 'leftover' char. I guess I'm using it in an incorrect fashion.

Thanks for your help, I didn't realize that happens with stdin!
 
Now you can see why getting even a simple C program right can be so difficult :) Any reason you have to do this in plain C? There are better alternatives that can help you to avoid the pitfalls of buffered input and string handling. C++, perl, python, etc. depending on what you need.
 
kpa said:
Now you can see why getting even a simple C program right can be so difficult :) Any reason you have to do this in plain C? There are better alternatives that can help you to avoid the pitfalls of buffered input and string handling. C++, perl, python, etc. depending on what you need.

Only my personal preference :)

I will probably trip up a lot, but it's all good as it's worth knowing - I'd rather learn like this than avoid the potential problems with higher level languages. C is lower, binds tighter to the OS, and doesn't 'depend' on other languages. Python is actually on my 'to do' list, but C has higher appeal.
 
Back
Top