Good afternoon! How are you all holding up today? I “accidentally” ate piece of cake at the cafe I’m currectly sitting in, even though I had promised myself not to eat sugar until next week. Fail. 😅

Don’t mind the English language, since this is an excerpt from a larger piece of code.

If I enter anything other than ‘Y’ and ‘N’ using a single character, the code works as I want it to, but, naturally, if I enter anything other than ‘Y’ and ‘N’ multiple times, the if is executed the same amount of times as characters entered, which is ugly. Trying to limit this with %1c also doesn’t work, since I suppose that only works with strings? Is this a limitation of scanf or rather how the logic is implemented?

Feel free to NOT provide the correct answer right away, but instead, give me the topic or the function to read up on. 😊

	char letter = '\0';  
	while(1) {  
		printf("nter the letter 'Y' or 'N': ");  
		scanf(" %c", &letter);  
		if (letter != 'Y' && letter != 'N') { //"broken" because multicharacter input executes this condition that many times.  
			printf("You have to enter 'Y' or 'N'! You have entered %c!\nE", letter);  
		}  
		else { break; }  
	}  
	printf("Good job! You have entered: %c.\n", letter);  

  • lemmysmash@piefed.social
    link
    fedilink
    English
    arrow-up
    6
    ·
    3 days ago

    I’m too lazy to confirm, but I think scanf (as well as many other I/O functions) works on top of the buffered input. I.e. when you scanned only one character on the first run of scanf but there are more left in the buffer, then subsequent calls will read from that buffer, e.g.

    printf("your prompt>")
    /* you type 123 */
    /* buffer contains: "123" */
    scanf(...)
    /* you scanned 1 char ("1") */
    /* buffer contains: "23" */
    printf("new prompt>");
    /* the prompt has been printed AFTER your previous input but the buffer hasn't been reset! */
    /* buffer contains: "23" */
    /* you type 456 */
    /* buffer contains: "23456" */
    scanf(...)
    /* scanf returns "2" */
    /* buffer contains: "3456" */
    

    In general you have two options:

    1. drain the buffer after / before each loop cycle
    2. use unbuffered I/O

    For both cases, do your research on how to do it :) That K&R from above should be a great start indeed.