0

The following method causes an error:

BOOL should_begin(void) {
    char yn;
    do {
        printf("Continue? [Y/N] ");
        yn = getchar();
        printf("\n");
        yn = toupper(yn);
        if (yn == 'N') {
            return FALSE;
        }
    } while (yn != 'Y');
    return TRUE;
}

The code executes normally until toupper() is reached, at which point there is a segmentation fault. I've seen questions like this where toupper() was called on part of a string, but it was only when someone tried to modify a literal.

So what gives? char yn shouldn't be read only, right? It's just a char, a single byte of data, I'm not reading a whole string, am I?


EDIT:

This is my main() function.

int main(int argc, char* argv[]) {

    /* just some printf()s with instructions */

    if (!should_begin()) {
        return 0;
    }

    /* then continue with rest of the program */

    return 0;
}
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
PC Luddite
  • 5,883
  • 6
  • 23
  • 39

1 Answers1

4

getchar() returns int. Some of the return values may not fit into a char.

Change yn to int yn.

Then, from the man page for toupper()

int toupper(int c);

If c is not an unsigned char value, or EOF, the behavior of these functions is undefined.

So, you need to check for EOF before passing yn to toupper().

FWIW, the toupper() is prototyped in ctype.h, you have to #include the same.

Community
  • 1
  • 1
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • 1
    You got it right. If an implementation uses an array of `1 << CHAR_BITS` to store char flags and index `c` blindly, this can cause segmentation fault. And specs have no issues with that and it is programmers responsibility. – Mohit Jain May 22 '15 at 07:46
  • Thanks @MohitJain sir for the added explanation. :-) – Sourav Ghosh May 22 '15 at 07:48
  • 1
    Alternative fix: `int input = getchar(); if(input == EOF) { error_handling(); } yn = (unsigned char)input;` – Lundin May 22 '15 at 08:43