Question

This function is extremely simple, or at least it should be. Some background: I'm building a chess program, and this function runs to assign promote values to pawns which have reached the end of the table. This is just the function to read promotion requests; the detection and actual promotion are one fxn higher. Here's the code:

    char promote (int player)
{

    char req, out;
    req = '0'; //shouldn't be necessary, and should be overwritten by scanf
    out = '0'; //just in case, should be overwritten
    printf("What piece would you like to promote to? (Q/N/R/B) \n");
    scanf("%c", &req);

    if (req == 'q' || req == 'Q')
    {
        out = 'q';
    }
    else if (req == 'r' || req == 'R')
    {
        out = 'r';
    }
    else if (req == 'n' || req == 'N')
    {
        out = 'n';
    }
    else if (req == 'b' || req == 'B')
    {
        out = 'i';
    }
    else if (req != 'q' && req != 'Q' && req != 'r' && req != 'R' && req != 'n' && req != 'N' && req != 'b' && req != 'B')
    {
        printf("req: %c, out: %c \n", req, out); //to test variable values
        printf("That character is invalid. Please enter another.\n");
        return promote(player);
    } //a simple else should suffice here. I put in the else if as a possible fix via redundancy (didn't work)

    if(player == 2)
    {
        out = toupper(out); //designates team by case
    }

    printf("Returning %c\n", out); //test out value again
    return out;
}

What SHOULD happen: Fxn scans for a single-character input, assigns it to req, checks req against eight possible choices. If it fits in one of the four bins, it assigns one of four values to out; if not, it prints a simple error message and returns its own call, at which point it scans, etc.

What DOES happen: When called, the scanf reads a \n (automatically), and immediately spits back the error message and loops upon itself without waiting for input. In the second loop, it works fine, with one caveat: when I enter an invalid character, it returns the proper error message, and upon calling itself again, goes through one loop of reading a \n before working again. Suggests the function itself, and not the error message, is to blame.

The output:

You can now promote your pawn. What piece would you like to promote to? (Q/N/R/B)
req:
, out: 0
That character is invalid. Please enter another.
What piece would you like to promote to? (Q/N/R/B)
q
Returning q

Any ideas? I've tried a dozen different things trying to fix this, and none of 'em have worked. Probably really simple like all my big mistakes are. Thanks for any help!

Was it helpful?

Solution

Looks like scanf is reading a newline, probably from a previous input. To fix this, you can simply loop scanf until you get something that isn't whitespace:

do {
    scanf("%c", &req);
} while(isspace(req));

As an aside, you can use tolower to convert a character to lowercase, which should simplify your req testing.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top