为什么我的嵌套if条件在C语言中不能正常工作?

huangapple go评论73阅读模式
英文:

Why does my nested if condition is not working properly in c?

问题

以下是翻译好的代码部分:

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

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

    printf("输入姓名: ");
    scanf("%[^\n]s", &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("输入年龄: ");
        scanf("%d", &age); 
        
        if (age % 2 == 0) {
            printf("哇,你很特别!\n");
        } else {
            printf("输入出生年份: ");
            scanf("%d", &birth);
        }
        
        if (birth % 2 != 0) {
            printf("明年你将变得特别。\n");
        } else {
            printf("哦,你仍然很特别!\n");
        }
    } else {
        printf("你很棒!\n");
    } // 嵌套条件结束

    return 0;
}

关于你提到的问题,agebirth 变量之间的问题可能是因为在名字以元音字母结尾的情况下,程序会要求输入年龄,然后根据年龄的奇偶性执行不同的操作。如果年龄是奇数,程序会继续要求输入出生年份,然后执行相应的操作。这是程序的预期行为,没有问题。如果你的问题不止这个,需要提供更多信息以便我更好地帮助你。

英文:

Here is my assignment:

> Ask the user to input their name.
>
> If their name ends with a vowel, ask them to input their age as well.
>
> If their age is even, print Wow, you&#39;re special!. Otherwise, if their age is odd, ask them to input their birth year.
>
> If their birth year is even, print Oh, you&#39;re still special!. Otherwise, print You will be special next year..
>
> If their name ends with a consonant though, print You&#39;re awesome!

Here is my code:

#include &lt;stdio.h&gt;
#include &lt;string.h&gt;

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

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

    return 0;
}

The problem is with the birth variable: the age and birth variables seems to be connected, because when the condition of age executes the condition of birth executes as well leading to a multiple executions of conditions.

答案1

得分: 3

&quot;%[^\n]s&quot; 是一个拼写错误。%[%s 是两个独立的 scanf 格式说明符 - 不能将它们结合在一起。你有一个 %[ 格式说明符,它读取字符直到换行符,并且然后格式字符串尝试匹配字面的 s 字符。

一个没有绑定宽度的 %[gets 一样危险。你必须提供一个 最大字段宽度说明符,它至多等于你的数组大小减一 (例如,%99[^\n]),以限制 scanf 读取的数据量,并防止缓冲区溢出。

&amp;name 的类型将是 char (*)[100],即一个数组的指针。%[ 期望一个 char *,简单来说就是一个 char 指针。将一个数组传递给函数会使其 衰减 为其第一个元素的指针 - 在这里不需要 &amp; 运算符。

你必须测试 scanf 的返回值是否是期望的 转换 数,否则你将在盲目操作,可能使用未初始化或其他不明确的值。

你应该初始化 birth,否则它的值是不明确的。如果 age 是偶数,你会尝试在 birth % 2 != 0 中使用这个不明确的值。

未纠正上述大部分问题将导致问题,包括未定义行为

一个更安全的示例程序如下:

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;

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

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

    size_t length = strlen(name);

    if (!length) {
        fprintf(stderr, &quot;&lt;name&gt; is empty!\n&quot;);
        return EXIT_FAILURE;
    }

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

    printf(&quot;Enter age: &quot;);

    if (1 != scanf(&quot;%d&quot;, &amp;age)) {
        fprintf(stderr, &quot;Could not read &lt;age&gt;.\n&quot;);
        return EXIT_FAILURE;
    }

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

        if (1 != scanf(&quot;%d&quot;, &amp;birth)) {
            fprintf(stderr, &quot;Could not read &lt;birth&gt;.\n&quot;);
            return EXIT_FAILURE;
        }
    }

    printf(&quot;NAME: &lt;%s&gt; AGE: &lt;%d&gt; BIRTH: &lt;%d&gt;\n&quot;, name, age, birth);
}
英文:

&quot;%[^\n]s&quot; is a typo. %[ and %s are two separate scanf specifiers - you do not combine them as such. What you have is a %[ specifier that reads characters until a newline, and then the format string attempts to match a literal s character.

An unbound %[ is as dangerous as gets. You most provide a maximum field-width specifier that is at most the size of your array minus one (e.g., %99[^\n]) to limit the amount of data scanf reads, and prevent a buffer overflow.

&amp;name would be of type char (*)[100], that is a pointer to an array. %[ expects a char *, simply a pointer to char. Passing an array to a function causes it to decay to a pointer to its first element - you do not need the &amp; operator here.

You must test the return value of scanf is the expected number of conversions, otherwise you are operating blindly, and may utilize uninitialized or otherwise indeterminate values.

You should initialize birth, otherwise its value is indeterminate. In the event that age is even, you would attempt to use this indeterminate value in birth % 2 != 0.

Failing to correct most of the above issues will lead to problems, including Undefined Behaviour.

A safer example program to study:

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;

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

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

	size_t length = strlen(name);

	if (!length) {
		fprintf(stderr, &quot;&lt;name&gt; is empty!\n&quot;);
		return EXIT_FAILURE;
	}

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

	printf(&quot;Enter age: &quot;);

	if (1 != scanf(&quot;%d&quot;, &amp;age)) {
		fprintf(stderr, &quot;Could not read &lt;age&gt;.\n&quot;);
		return EXIT_FAILURE;
	}

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

		if (1 != scanf(&quot;%d&quot;, &amp;birth)) {
			fprintf(stderr, &quot;Could not read &lt;birth&gt;.\n&quot;);
			return EXIT_FAILURE;
		}
	}

	printf(&quot;NAME: &lt;%s&gt; AGE: &lt;%d&gt; BIRTH: &lt;%d&gt;\n&quot;, name, age, birth);
}

答案2

得分: 2

以下是您要翻译的内容:

"The conditions expressed in the assignment imply that you only test the birth year if the age is even... otherwise you do not even ask for the birth age. Your tests are not properly nested.

Note that scanf(&quot;%[^\n]s&quot;, &amp;name); is incorrect:

  • you must tell scanf() the maximum number of characters to store to the destination array to avoid a potential buffer overflow;
  • &amp;name is not the expected type, you should just pass name, which is an array that is converted automatically to a pointer to its first element when passed as an argument or used in an expression (except as an argument to sizeof or alignof);
  • the s in the format is meaningless. Use scanf(&quot; %99[^\n]&quot;, name) instead;
  • test the return value to detect invalid or missing input and avoid undefined behavior later in the program.

Also note that letters can be uppercase and the last character may be neither a vowel nor a consonant (eg: X Æ A-12).

Here is a modified version, more consistent with the assignment:

#include &lt;stdio.h&gt;
#include &lt;string.h&gt;

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

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

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

The conditions expressed in the assignment imply that you only test the birth year if the age is even... otherwise you do not even ask for the birth age. Your tests are not properly nested.

Note that scanf(&quot;%[^\n]s&quot;, &amp;name); is incorrect:

  • you must tell scanf() the maximum number of characters to store to the destination array to avoid a potential buffer overflow;
  • &amp;name is not the expected type, you should just pass name, which is an array that is converted automatically to a pointer to its first element when passed as an argument or used in an expression (except as an argument to sizeof or alignof);
  • the s in the format is meaningless. Use scanf(&quot; %99[^\n]&quot;, name) instead;
  • test the return value to detect invalid or missing input and avoid undefined behavior later in the program.

Also note that letters can be uppercase and the last character may be neither a vowel nor a consonant (eg: X Æ A-12).

Here is a modified version, more consistent with the assignment:

#include &lt;stdio.h&gt;
#include &lt;string.h&gt;
int main() {
// variables
char name[100];
int age, birth;
printf(&quot;Enter name: &quot;);
// read up to 99 characters, skipping initial white space
if (scanf(&quot; %99[^\n]&quot;, name) != 1) {
fprintf(stderr, &quot;invalid or missing input for name\n&quot;);
return 1;
}
// formula for getting last letter of the name
size_t len = strlen(name);
if (len == 0) {
fprintf(stderr, &quot;invalid empty name\n&quot;);
return 1;
}
char last = name[len - 1];
// test if last character is a vowel (trailing &#39;y&#39; is a vowel)
if (strchr(&quot;aeiouyAEIOUY&quot;, last)) {
printf(&quot;Enter age: &quot;);
if (scanf(&quot;%d&quot;, &amp;age) != 1) {
fprintf(stderr, &quot;invalid or missing input for age\n&quot;);
return 1;
}
if (age % 2 == 0) {
printf(&quot;Wow, you&#39;re special!\n&quot;);
} else {
printf(&quot;Enter birth year: &quot;);
if (scanf(&quot;%d&quot;, &amp;birth) != 1) {
fprintf(stderr, &quot;invalid or missing input for birth\n&quot;);
return 1;
}
if (birth % 2 == 0) {
printf(&quot;Oh, you&#39;re still special!\n&quot;);
} else {
printf(&quot;You will be special next year.\n&quot;);
}
}
} else {
// the last character is not a vowel, test if it is a consonant
if (strchr(&quot;bcdfghjklmnprstvwxzBCDFGHJKLMNPQRSTVWXZ&quot;, last) {
printf(&quot;You&#39;re awesome!\n&quot;);
}
}
return 0;
}

答案3

得分: 0

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

英文:

of course you get two outputs, your if statements regarding age and birth are parallel. Shouldn't your birth block be nested inside of the else block for age?

huangapple
  • 本文由 发表于 2023年2月18日 22:53:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/75494145.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定