结合fgets/scanf和switch读取字符

pbgvytdp  于 2023-06-21  发布在  其他
关注(0)|答案(2)|浏览(130)

我想创建一个菜单。我将输入一个字符,并根据什么字符的一些文本将被打印。对我来说,问题在于下面代码中的默认选项。我希望它能识别所有不是1,2,3或q的东西。不仅仅是字符,还有字符串。如果输入是“sf<ssad”,我不希望它打印“Invalid input”7次,只打印一次。另外,如果我输入“qf<<dsc”,即使第一个字符是有效的,我也想把整个输入算作无效的,因为它不止一个字符。类似地,像“1 sd <j”这样的输入不应该打印结果“hello”。相反,它应该将其打印为“Invalid input”。
我想要一个可靠的代码,最好不包括scanf,是容易的眼睛。我尝试了以下操作:

#include <stdio.h>
int main(void) {
char cmd;

do {
    printf("Enter 1 to print hello, enter 2 to print world, enter 3 to print hello world and enter q to quit\n");
    printf("Enter: ");
    scanf(" %c", &cmd);

    switch(cmd) {
       case '1' : printf("hello\n"); break;
       case '2' : printf("world\n"); break;
       case '3' : printf("hello world\n"); break;
       case 'q' : printf("Exiting...\n"); break;
       default : printf("Invalid input!\n"); break; 
    }
} while(cmd!='q');

return 0;
}

这是不够的,因为如果我输入“sf<ssad”,“Invalid input”将被打印7次。我尝试了其他版本,但他们有类似的问题。我的一个想法是使用fgets,然后取第一个字符,然后使用atoi,尽管我不确定它会是什么样子。先谢谢你了。

m3eecexj

m3eecexj1#

调用fgets(),检查错误,然后将cmd设置为该行的第一个字符。那么代码的其余部分是相同的。

char line[100];
char cmd;
do {
    printf("Enter 1 to print hello, enter 2 to print world, enter 3 to print hello world and enter q to quit\n");
    printf("Enter: ");
    char *res = fgets(line, sizeof line, stdin);
    if (!res) {
        break;
    }

    cmd = line[0];
    switch(cmd) {
       case '1' : printf("hello\n"); break;
       case '2' : printf("world\n"); break;
       case '3' : printf("hello world\n"); break;
       case 'q' : printf("Exiting...\n"); break;
       default : printf("Invalid input!\n"); break; 
    }

} while (cmd != 'q');
kq4fsx7k

kq4fsx7k2#

如果输入是“sf<ssad”,我不希望它打印“Invalid input”7次,只打印一次。
在这种情况下,您应该一次读取整行输入,而不是一次读取一个字符。为此,我建议您使用函数fgets而不是scanf
下面是一个例子:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

void get_line_from_user( const char prompt[], char buffer[], int buffer_size );

int main( void )
{
    bool quit = false;

    while ( !quit )
    {
        char line[200];

        //print menu
        printf(
            "Menu:\n"
            "Enter 1 to print hello,\n"
            "enter 2 to print world,\n"
            "enter 3 to print hello world,\n"
            "or enter q to quit\n"
        );

        //get one line of input from the user
        get_line_from_user( "Enter choice: ", line, sizeof line );

        //verify that user entered exactly one character
        if ( line[0] == '\0' || line[1] != '\0' )
        {
            printf( "Error: Please only enter a single character!\n\n" );
            continue;
        }

        switch( line[0] )
        {
            case '1':
                printf( "hello\n" );
                break;
            case '2':
                printf( "world\n" );
                break;
            case '3':
                printf( "hello world\n" );
                break;
            case 'q':
                printf( "Exiting...\n" );
                quit = true;
                break;
            default:
                printf("Invalid input!\n");
        }

        //add spacing
        printf( "\n" );
    }

    return EXIT_SUCCESS;
}

//This function will read exactly one line of input from the
//user. It will remove the newline character, if it exists. If
//the line is too long to fit in the buffer, then the function
//will automatically reprompt the user for input. On failure,
//the function will never return, but will print an error
//message and call "exit" instead.
void get_line_from_user( const char prompt[], char buffer[], int buffer_size )
{
    for (;;) //infinite loop, equivalent to while(1)
    {
        char *p;

        //prompt user for input
        fputs( prompt, stdout );

        //attempt to read one line of input
        if ( fgets( buffer, buffer_size, stdin ) == NULL )
        {
            printf( "Error reading from input!\n" );
            exit( EXIT_FAILURE );
        }

        //attempt to find newline character
        p = strchr( buffer, '\n' );

        //make sure that entire line was read in (i.e. that
        //the buffer was not too small to store the entire line)
        if ( p == NULL )
        {
            int c;

            //a missing newline character is ok if the next
            //character is a newline character or if we have
            //reached end-of-file (for example if the input is
            //being piped from a file or if the user enters
            //end-of-file in the terminal itself)
            if ( (c=getchar()) != '\n' && !feof(stdin) )
            {
                if ( c == EOF )
                {
                    printf( "Error reading from input!\n" );
                    exit( EXIT_FAILURE );
                }

                printf( "Input was too long to fit in buffer!\n" );

                //discard remainder of line
                do
                {
                    c = getchar();

                    if ( c == EOF )
                    {
                        //this error message will be printed if either
                        //a stream error or an unexpected end-of-file
                        //is encountered
                        printf( "Error reading from input!\n" );
                        exit( EXIT_FAILURE );
                    }

                } while ( c != '\n' );

                //reprompt user for input by restarting loop
                continue;
            }
        }
        else
        {
            //remove newline character by overwriting it with
            //null character
            *p = '\0';
        }

        //input was ok, so break out of loop
        break;
    }
}

此程序具有以下行为:

Menu:
Enter 1 to print hello,
enter 2 to print world,
enter 3 to print hello world,
or enter q to quit
Enter choice: sf<ssad
Error: Please only enter a single character!

Menu:
Enter 1 to print hello,
enter 2 to print world,
enter 3 to print hello world,
or enter q to quit
Enter choice: qsf<dsf
Error: Please only enter a single character!

Menu:
Enter 1 to print hello,
enter 2 to print world,
enter 3 to print hello world,
or enter q to quit
Enter choice: 1
hello

Menu:
Enter 1 to print hello,
enter 2 to print world,
enter 3 to print hello world,
or enter q to quit
Enter choice: 2
world

Menu:
Enter 1 to print hello,
enter 2 to print world,
enter 3 to print hello world,
or enter q to quit
Enter choice: 3
hello world

Menu:
Enter 1 to print hello,
enter 2 to print world,
enter 3 to print hello world,
or enter q to quit
Enter choice: q
Exiting...

相关问题