Home > Software design >  Issues with scanf() and accepting user input
Issues with scanf() and accepting user input

Time:09-24

I am trying to take in user input with spaces and store it in an array of characters. After, I want to take in a single character value and store it as a char. However, when I run my code, the prompt for the character gets ignored and a space is populated instead. How can I take in an array of chars and still be allowed to prompt for a single character after?

void main()
{
    char userIn[30];
    char findChar;


    printf("Please enter a string: ");
    scanf("%[^\n]s", userIn);

    printf("Please enter a character to search for: ");
    scanf("%c", &findChar);

    //this was put here to see why my single char wasnt working in a function I had
    printf("%c", findChar);

}

CodePudding user response:

scanf("%c", &findChar); reads the next character pending in the input stream. This character will be the newline entered by the user that stopped the previous conversion, so findChar will be set to the value '\n', without waiting for any user input and printf will output this newline without any other visible effect.

Modify the call as scanf(" %c", &findChar) to ignore pending white space and get the next character from the user, or more reliably write a loop to read the read and ignore of the input line.

Note also that scanf("%[^\n]s", userIn); is incorrect:

  • scanf() may store bytes beyond the end of userIn if the user types more than 29 bytes of input.
  • the s after the ] is a bug, the conversion format for character classes is not a variation of the %s conversion.

Other problems:

  • void is not a proper type for the return value of the main() function.
  • the <stdio.h> header is required for this code.

Here is a modified version:

#include <stdio.h>

int main() {
    char userIn[30];
    int c;
    char findChar;
    int i, found;

    printf("Please enter a string: ");
    if (scanf(")[^\n]", userIn) != 1) {
        fprintf(stderr, "Input failure\n");
        return 1;
    }
    /* read and ignore the rest of input line */
    while ((c = getchar()) != EOF && c != '\n')
        continue;

    printf("Please enter a character to search for: ");
    if (scanf("%c", &findChar) != 1) {
        fprintf(stderr, "Input failure\n");
        return 1;
    }

    printf("Searching for '%c'\n", findChar);
    found = 0;
    for (i = 0; userIn[i] != '\0'; i  ) {
        if (userIn[i] == findChar) {
            found  ;
            printf("found '%c' at offset %d\n", c, i);
        }
    }
    if (!found) {
        printf("character '%c' not found\n", c);
    }
    return 0;
}

CodePudding user response:

scanf("%[^\n]s", userIn); is a bit weird. The s is guaranteed not to match, since that character will always be \n. Also, you should use a width modifier to avoid a buffer overflow. Use scanf(")[^\n]", userIn); That alone will not solve the problem, since the next scanf is going to consume the newline. There are a few options. You could consume the newline in the first scanf with:

scanf(")[^\n]%*c", userIn);

or discard all whitespace in the next call with

scanf(" %c", &findChar);

The behavior will differ on lines of input that exceed 29 characters in length or when the user attempts to assign whitespace to findChar, so which solution you use will depend on how you want to handle those situations.

  • Related