用 C 语言编写的基于文本的游戏的名称比较 [duplicate]

Name comparisson for text based game written in C [duplicate]

提问人:Eminion 提问时间:7/5/2023 更新时间:7/6/2023 访问量:94

问:

所以,我正在尝试制作一个基于文本的游戏来帮助人们学习 linux,我正在努力做到这一点,如果你的名字是 Linus Torvalds,而不是你的指南是 Linus Torvalds,那将是 Richard Stallman,问题是输入任何名字,打印屏幕都会显示指南是 Richard Stallman。 (顺便说一句,使用 C 顺便说一句)

在这里编码:

<!--语言:c -->


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

//Global variables
char name[15];
char yesno[1];

//Main
int main(){
    system("clear");
    printf("???: Hello adventurer, are you here to learn Linux?\n");
    printf("y/n\n");

    scanf("%c", yesno);

    if (strcmp("n", yesno)){
        printf("???: Great!, What is your name?\n");
        
        scanf("%s", name);
        
        if("Linus Torvalds\n"){
            printf("Achievment complete: In God We Trust\n");
            printf("Nice to meet you!, my name is Richard Stallman.\n");
        }else {
            printf("Nice to meet you!, my name is Linus Torvalds.\n");
        }
    }
    else if (strcmp("y", yesno)){
        printf("Ok!, bye!");
    }else {
        printf("That's not an answer.\n");
    }
}

我尝试过 strcmp、mallocs、plain conditions,但它不起作用,如果有人有答案,那就太好了。

附言

请尝试在您的答案中包含代码和/或使它们尽可能详细,Thaks。

c if 条件语句 比较 dynamic-memory-allocation

评论

3赞 dimich 7/5/2023
strcmp()比较两个字符串(即以 null 结尾的字符数组)。 不是字符串。yesno
0赞 Some programmer dude 7/5/2023
另请注意,这是区分大小写的。字符串等于 strinbg 。由于某种原因,C 没有与大小写的无关的比较函数,但编译器和环境有自己的实现(例如 或 )。strcmp"foo""Foo"strcasecmpstricmp
0赞 Andreas Wenzel 7/5/2023
旁注:不是清除屏幕的推荐方法。虽然它现在可能对你有用,但一旦你在编程方面更高级,你可能会想看看替代方案system("clear");
0赞 Tom Karzes 7/5/2023
你认为有什么作用?提示:在此上下文中,它将字符串指针与 进行比较。既然不是,结果就为真。所以这相当于.if("Linus Torvalds\n")NULLif (1)
1赞 Tom Karzes 7/5/2023
此外,由于是单字符数组,而不是以 null 结尾的数组,因此不能将其视为字符串。如果希望它是单字符字符串,则需要使用两个元素声明它,并将第二个元素设置为空字符。yesno

答:

2赞 Andreas Wenzel 7/5/2023 #1

与格式说明符一起使用将只能读取单个单词。如果你想阅读由几个单词组成的整行(例如),那么我建议你改用 fgets。但是,请注意有关混合和 .另外,请参阅有关如何从输入中删除换行符的问题。我建议您根本不用于用户输入,而是始终使用 .scanf%s"Linus Torvalds\n"fgetsscanffgetsscanffgets

该条件没有意义,因为该条件将始终为真。如果要比较 的内容,则需要使用 strcmp 函数。if("Linus Torvalds\n")name"Linus Torvalds\n"

另外,线

if (strcmp("n", yesno)){

是错误的,因为该函数要求其两个参数都是指向一个字符串的指针,即指向以 null 字符结尾的字符序列。但是,不是指针。 也是错误的,因为这样的指针只会指向单个字符,而不是指向以 null 字符结尾的字符序列。strcmpyesno&yesno

如果两个字符串匹配,则该函数将返回零,如果不匹配,则返回非零。因此,您可能希望将 的返回值与零进行比较。strcmpstrcmp

我建议你像这样重写你的程序:

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

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

int main( void )
{
    char input[200];

    get_line_from_user(
        "Hello adventurer, are you here to learn Linux? (y/n) ",
        input, sizeof input
    );

    if ( strcmp( input, "y" ) == 0 )
    {
        get_line_from_user(
            "Great! What is your name? ",
            input, sizeof input
        );
        
        if ( strcmp( input, "Linus Torvalds" ) == 0 )
        {
            printf( "Achievement complete: In God We Trust\n" );
            printf( "Nice to meet you! My name is Richard Stallman.\n" );
        }
        else
        {
            printf( "Nice to meet you! My name is Linus Torvalds.\n" );
        }
    }
    else if ( strcmp( input, "n" ) == 0 )
    {
        printf( "Ok! Bye!" );
    }
    else 
    {
        printf( "That's not an answer.\n" );
    }
}

//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;
    }
}

此程序具有以下行为:

Hello adventurer, are you here to learn Linux? (y/n) y
Great! What is your name? Jimmy
Nice to meet you! My name is Linus Torvalds.
Hello adventurer, are you here to learn Linux? (y/n) y
Great! What is your name? Linus Torvalds
Achievement complete: In God We Trust
Nice to meet you! My name is Richard Stallman.
Hello adventurer, are you here to learn Linux? (y/n) n
Ok! Bye!
Hello adventurer, are you here to learn Linux? (y/n) sdfsdgf
That's not an answer.

评论

0赞 Eminion 7/6/2023
只是一个问题,代码的最后一部分做什么?
0赞 Eminion 7/6/2023
我的意思是以 for(;;) 开头的部分{
0赞 Andreas Wenzel 7/6/2023
@Eminion:我的代码中有很多关于该函数的注释。有什么你不明白的具体内容吗?循环是一个无限循环,它将永远循环,直到输入有效。在这种情况下,将执行该语句,该语句将跳出循环。就函数而言,如果输入足够短以适合内存缓冲区,则该输入有效。如果它太长而无法放入缓冲区,则循环将不会终止,并且将重新提示用户输入。get_line_from_userfor (;;)breakget_line_from_user
0赞 Eminion 7/7/2023
啊,谢谢,感谢您的帮助以及您花时间重写我的代码。
0赞 Andreas Wenzel 7/8/2023
@Eminion:你可以用这个简短的测试程序来测试我的函数循环的行为。在那个简短的测试程序中,我将缓冲区大小减少到只有 5 个字符,因此它只能存储 4 个输入字符(加上终止 null 字符)。您所要做的就是按绿色的“运行”按钮进行测试。如果您输入的输入太长,则该函数将自动提示您输入用户。如果您想要的只是一条错误消息,并且在这种情况下程序退出,则不需要循环。get_line_from_user