繁体   English   中英

输入年龄的第二个 scanf 不允许输入

[英]The second scanf to input the age doesn't allow input

嘿,我一直在努力解决我遇到的这个问题。 第二个 scanf 不允许输入 integer。 我已经检查以确保一切都是正确的,但它仍然是同一件事。 我错过了什么吗? Output 停在“输入你今年年底的年龄:”

int main() {

    int age;
    char usrname;
    
    printf("Hello, Welcome to the birth year calculator!");
    printf("\n\nEnter Your Name: ");
    scanf("%c", &usrname);

    printf("Enter your age at the end of this year: ");
    scanf("%d", &age);

    return 0;
}

除了char usrname的奇怪选择之外,它对我有用。 如果您在输入之前输入超过 1 个字母,将导致第二次scanf()失败,您将看到错误检查。 如果您不希望第一个提示的任何输入渗入第二个提示,那么您需要刷新输入 stream 之间。 最小化 scope 变量:

#include <stdio.h>

int main() {
    printf("\n\nEnter Your Name: ");
    char usrname;
    if(scanf("%c", &usrname) != 1) {
        printf("usrname failed\n");
        return 1;
    }
    printf("Enter your age at the end of this year: ");
    int age;
    if(scanf("%d", &age) != 1) {
        printf("age failed\n");
        return 1;
    }
    printf("name=%c, age=%d\n", usrname, age);
    return 0;
}

您可能希望使用字符串而不是字符作为 usrname。 如果您的用户名包含空格,那么您最好使用fgets()而不是scanf()读取一行。 还将年龄更改为未签名。

#include <stdio.h>
#define TADMAN_IS_NOT_STINGY 254
#define str(s) str2(s)
#define str2(s) #s

int main() {
    printf("\n\nEnter Your Name: ");
    char usrname[TADMAN_IS_NOT_STINGY+1];
    if(scanf("%" str(TADMAN_IS_NOT_STINGY) "s", usrname) != 1) {
        printf("usrname failed\n");
        return 1;
    }
    printf("Enter your age at the end of this year: ");
    unsigned age;
    if(scanf("%u", &age) != 1) {
        printf("usrname failed\n");
        return 1;
    }
    printf("name=%s, age=%u\n", usrname, age);
    return 0;
}

问题是以下两行:

printf("\n\nEnter Your Name: ");
scanf("%c", &usrname);

您告诉用户输入包含多个字符的内容,但您只是从输入 stream 中提取单个字符并将其写入usrname

例如,如果您输入Michael ,那么您将从输入 ZF7B44CFFAFD5C52223D5498196C8A2E7BZ 中提取M ,将ichael留在 stream 上。

之后,您将执行该行

scanf("%d", &age);

这将尝试将输入 stream 上剩余的内容转换为 integer。 但是,这将失败,因为无法将ichael转换为 integer。

一般不推荐使用scanf进行基于行的用户输入。 这是因为scanf的行为并不直观。 例如,如上所示,它并不总是在一次 function 调用中读取一行输入,这可能会导致麻烦,就像它对您所做的那样。

出于这个原因,通常建议使用 function fgets代替,如果可能,它将始终准确读取一行输入。 将一行输入读取为字符串后,您可以尝试将其转换为 integer,例如使用 function strtol

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

int main()
{
    char usrname[200];
    char line[200];
    int age;
    
    printf("Hello, Welcome to the birth year calculator!");

    printf("\n\nEnter Your Name: ");
    fgets( usrname, sizeof usrname, stdin );

    //remove newline character
    usrname[strcspn(usrname,"\n")] = '\0';

    printf("Enter your age at the end of this year: ");
    fgets( line, sizeof line, stdin );
    age = strtol( line, NULL, 10 );

    return 0;
}

这就是我所做的,它似乎工作得很好。

我创建了一个 class,不确定这是否有必要

class Person {
    std::string userName;
    int age;
}

main() {
    Person shalofty;
    std::cout << "Enter name and age" << std::endl;
    std::cin >> shalofty.userName;
    std::cin >> shalofty.age;
}

不同的人看到不同的优先事项并提供不同的建议。 在这里,在注释代码中,是另一个接近原始版本但经过修饰的版本

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

int main()
{
    char usrname[200] = { 0 }; // ALWAYS initialise variables
    
    printf("Hello, Welcome to the birth year calculator!");

    printf("\n\nEnter Your Name: ");

    if( scanf( "%[^\n]", usrname ) != 1 ) { // test return codes
        fprintf( stderr, "Scanf failed\n" );
        exit( EXIT_FAILURE );
    }

    // remove trailing '\n' from the name entered
    usrname[ strcspn( usrname, "\n" ) ] = '\0';

    int usrage = 0; // define and initialise variables close to use
    printf("Enter your age at the end of this year: ");

    if( scanf( "%d", &usrage ) != 1 ) { // test return codes
        fprintf( stderr, "Scanf failed\n" );
        exit( EXIT_FAILURE );
    }

    // do something with the user's input
    printf( "Hello %s, who will be %d years old at year's end\n", usrname, usrage );

    return 0;
}

Output

Hello, Welcome to the birth year calculator!

Enter Your Name: Foo Bar
Enter your age at the end of this year: 42
Hello Foo Bar, who will be 42 years old at the end of this year

第一个scanfstdin读取1字符(因为usrname是char而不是char数组),然后如果stdin为空->第二个scanf将等待输入,否则第二个scanf将在第二个提示打印后自动执行.

在您的情况下,我想在第一个提示符下,您输入了超过 1 个字符,在这种情况下,第二个scanf不会等待而是使用第一个scanf未读取的额外输入运行。 例如,如果您为第一个提示输入john ,则第一个scanf采用j ,第二个scanf采用ohn并尝试转换为int

要解决此问题,请为usrname使用 char 数组,例如char usrname[128] = {0}或不要在第一个提示符处输入超过 1 个字符(对于名称)。

int main() {

    int age;
    char usrname[128] = {0};
    
    printf("Hello, Welcome to the birth year calculator!");
    printf("\n\nEnter Your Name: ");
    scanf("%s", usrname);

    printf("Enter your age at the end of this year: ");
    scanf("%d", &age);

    return 0;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM