windows 为什么我的嵌套if条件在c中不能正常工作?

fcg9iug3  于 2023-02-20  发布在  Windows
关注(0)|答案(3)|浏览(143)

下面是我的作业:
要求用户输入其姓名。
如果他们的名字以元音结尾,请他们也输入年龄。
如果他们的年龄是偶数,打印Wow, you're special!。否则,如果他们的年龄是奇数,请他们输入出生年份。
如果他们的出生年份是偶数,则打印Oh, you're still special!。否则,打印You will be special next year.
如果他们的名字以辅音结尾,打印You're awesome!
下面是我的代码:

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

int main() {
    // variables
    char name[100];
    int age, birth;

    printf("Enter name: ");
    scanf("%[^\n]s", &name);
    
    // formula for getting last letter of the name
    int size = strlen(name);
    int last = size - 1;
    
    if (name[last] == 'a' || name[last] == 'e' || name[last] == 'i' ||
        name[last] == 'o' || name[last] == 'u') {
        printf("Enter age: ");
        scanf("%d", &age); 
        
        if (age %2 == 0) {
            printf("Wow, you're special!\n");
        } else {
            printf("Enter birth year: ");
            scanf("%d", &birth);
        }
        
        if (birth % 2 != 0) {
            printf("You will be special next year.\n");
        } else {
           printf("Oh, you're still special!\n");
        }
    } else {
        printf("You're awesome!\n");
    } // end of nested if

    return 0;
}

birth变量存在问题:变量agebirth看起来是相连的,因为当年龄条件执行时,出生条件也执行,从而导致条件的多次执行。

bvuwiixz

bvuwiixz1#

"%[^\n]s"是一个输入错误。%[%s是两个单独的scanf说明符-您不能将它们这样组合在一起。您拥有的是一个%[说明符,它读取字符直到换行符,然后格式字符串尝试匹配一个文本s字符。
未绑定的%[as dangerous as gets。您最好提供一个 maximum field-width specifier,它最多等于数组大小减1(例如%99[^\n]),以限制scanf读取的数据量,并防止缓冲区溢出。
&name的类型为char (*)[100],即指向数组的指针。%[需要char *,即指向 char 的指针。将数组传递给函数会导致它 * 衰减 * 为指向其第一个元素的指针-此处不需要&运算符。
必须测试scanf的返回值是否为预期的 * 转换 * 数,否则就是盲目操作,可能会使用未初始化或 * 不确定 * 的值。
您应该初始化birth,否则它的值为 indeterminate。如果age为偶数,您将尝试在birth % 2 != 0中使用此不确定值。
未能纠正上述大多数问题将导致问题,包括Undefined Behaviour
要学习的更安全的示例程序:

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

int main(void)
{
    char name[100];
    int age;
    int birth = 0;

    printf("Enter name: ");
    if (1 != scanf("%99[^\n]", name)) {
        fprintf(stderr, "Could not read <name>.\n");
        return EXIT_FAILURE;
    }

    size_t length = strlen(name);

    if (!length) {
        fprintf(stderr, "<name> is empty!\n");
        return EXIT_FAILURE;
    }

    if (!strchr("aeiou", name[length - 1])) {
        puts("Name does not end in a vowel.");
        return EXIT_SUCCESS;
    }

    printf("Enter age: ");

    if (1 != scanf("%d", &age)) {
        fprintf(stderr, "Could not read <age>.\n");
        return EXIT_FAILURE;
    }

    if (age % 2 != 0) {
        printf("Enter birth: ");

        if (1 != scanf("%d", &birth)) {
            fprintf(stderr, "Could not read <birth>.\n");
            return EXIT_FAILURE;
        }
    }

    printf("NAME: <%s> AGE: <%d> BIRTH: <%d>\n", name, age, birth);
}
vsaztqbk

vsaztqbk2#

赋值语句中所表达的条件意味着,如果年龄为偶数,则只测试出生年份......否则,甚至不要求输入出生年龄。您的测试没有正确嵌套。
请注意,scanf("%[^\n]s", &name);是不正确的:

  • 您必须告诉scanf()要存储到目标数组的最大字符数,以避免潜在的缓冲区溢出;
  • &name不是预期的类型,您应该只传递name,这是一个数组,当作为参数传递或在表达式中使用时(作为sizeofalignof的参数除外),它会自动转换为指向其第一个元素的指针;
  • 格式中的s没有意义,请使用scanf(" %99[^\n]", name);
  • 测试返回值以检测无效或丢失的输入,并避免程序中稍后出现未定义的行为。

还应注意,字母可以大写,最后一个字符可以既不是元音也不是辅音(例如:X Æ A-12)。
下面是一个修改过的版本,与作业更加一致:

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

int main() {
    // variables
    char name[100];
    int age, birth;

    printf("Enter name: ");
    // read up to 99 characters, skipping initial white space
    if (scanf(" %99[^\n]", name) != 1) {
        fprintf(stderr, "invalid or missing input for name\n");
        return 1;
    }
    
    // formula for getting last letter of the name
    size_t len = strlen(name);
    if (len == 0) {
        fprintf(stderr, "invalid empty name\n");
        return 1;
    }

    char last = name[len - 1];
    // test if last character is a vowel (trailing 'y' is a vowel)
    if (strchr("aeiouyAEIOUY", last)) {
        printf("Enter age: ");
        if (scanf("%d", &age) != 1) {
            fprintf(stderr, "invalid or missing input for age\n");
            return 1;
        }
        if (age % 2 == 0) {
            printf("Wow, you're special!\n");
        } else {
            printf("Enter birth year: ");
            if (scanf("%d", &birth) != 1) {
                fprintf(stderr, "invalid or missing input for birth\n");
                return 1;
            }
            if (birth % 2 == 0) {
                printf("Oh, you're still special!\n");
            } else {
                printf("You will be special next year.\n");
            }
        }
    } else {
        // the last character is not a vowel, test if it is a consonant
        if (strchr("bcdfghjklmnprstvwxzBCDFGHJKLMNPQRSTVWXZ", last) {
            printf("You're awesome!\n");
        }
    }
    return 0;
}
eoigrqb6

eoigrqb63#

当然你会得到两个输出,你的if语句中关于年龄和出生的语句是并行的,你的出生块不应该嵌套在else块中吗?

相关问题