我正在尝试创建一个布尔标志,当输入无效的输入代码时,该标志将输出错误消息。这是一个课堂作业,我只是学习C所以请原谅格式化,并通知我是否可以改进。如果输入或输出变量不正确,除了输出错误消息之外,我有代码执行所有操作。我相信这是代码的布尔检查部分的错误。诊断会很好。
此代码将:
参数:
先谢谢。
# include <stdio.h>
int main() {
char $ = $;
char Y = Y;
char E = E;
char in_currency, out_currency;
char flag = 1;
char new_line;
float in_value;
float out_value;
//Calculation variables
printf("Enter the source currency: ");
scanf("%c%c", &in_currency, &new_line);
printf("Enter the destination currency: ");
scanf("%c%c", &out_currency, &new_line);
if ( ( in_currency || out_currency ) != ( '$' || 'Y' || 'E' ) )
flag = 0;
printf("Enter the value: ");
scanf("%f%c", &in_value, &new_line);
//Calculations
if (flag) {
printf("%c%.2f = %c%.2f \n", in_currency, in_value, out_currency, out_value);
}
else {
printf("There was an error with the input. \n");
}
return 0;
}
答案 0 :(得分:2)
感谢@JonathanLeffler的精彩评论。
我认为这可能是由于你的if语句的逻辑顺序
if ( ( in_currency || out_currency ) != ( '$' || 'Y' || 'E' ) )
flag = 0;
你打算做的事情如下
if (
(in_currency == '$' || in_currency == 'Y' || in_currency == 'E')
||
( out_currency == '$' || out_currency == 'Y' || out_currency == 'E')
) flag = 0;
这是由于您的原始行的评估方式。 (in_currency || out_currency)
注意C++ standard(第6.8.4.1节)陈述
如果表达式将une等于0,则执行子语句。
与输入相同 (in_currency!= 0 || out_currency =!0) 请注意,测试单个值将始终针对非零进行测试,有时会被视为“真实”值。
简而言之,if语句的第一部分将始终返回true,因为两个测试(非零字符值)都等于true。
可以看到这一点(不为零 OR out 不为零),因为两个值都不为零,两个测试都等于变为真实,成为(真 OR 真) - 显然这反过来也是如此。
if语句的后半部分差别不大
( '$' || 'Y' || 'E' )
这也等同于(真或假或真),因此总是等于真如下:
( '$' != 0 || 'Y' != 0 || 'E' != 0)
最后,这会分解为您的代码阅读:
if ((in_currency != 0 || out_currency =! 0) != ( '$' != 0 || 'Y' != 0 || 'E' != 0))
if ((true || true) != ( true || true || true))
if ((true) != (true))
显然,这将始终等于false,因为true永远不等于true(除非某些通用常量更改; - )
结果是你的旗帜总是假的。 - 始终
我已经给你替换它的行,而是分别测试每个可能的情况场景并比较结果。
您可以将其视为
if
in_currency **is equal to** '$' *or*
in_currency **is equal to** 'Y' *or*
in_currency **is equal to** 'E'
or
out_currency **is equal to** '$' *or*
out_currency **is equal to** 'Y' *or*
out_currency **is equal to** 'E'
then flag = 0;
[编辑]
用户Turboc在下面回答说您可能希望使用&amp;&amp; (和)而不是这两个陈述之间的或。(请原谅我在此处提供此信息,但我还不能对答案发表评论)
这取决于您打算如何评估您的语句 - 如果您希望该标志等于false(0)如果货币是上述任何一种,对于输出或输入,那么情况并非如此)。
但是,如果您希望声明为真,只要货币是以上之一,您就会使用以下
if
in_currency **is equal to** '$' *or*
in_currency **is equal to** 'Y' *or*
in_currency **is equal to** 'E'
and
out_currency **is equal to** '$' *or*
out_currency **is equal to** 'Y' *or*
out_currency **is equal to** 'E'
then flag = 1;
但是,如果是这种情况,您可能希望确定哪种答案是解决问题的更有效方法。
答案 1 :(得分:1)
将一些评论和其他笔记转换为答案
这些语句:
char $ = $; char Y = Y; char E = E;
通过使用自己的未初始化值初始化变量来调用未定义的行为(或者至少不会实现任何有用的行为)。变量$
在标准C中无效;您可以找到允许它的C编译器(特别是如果您使用VMS)。遗憾的是,这不是一个好的开始。其余代码不使用变量的事实是另一个问题。你可以简单地删除它们。请注意,如果用户输入了来源货币&#39;作为GPB,
new_line
变量不会包含换行符。使用" %c"
(空格,百分比,&#39; c&#39;)作为格式字符串可能会做得更好;它会跳过(可选)前导空格(空格,制表符,换行符),然后是一个字符。重复目标货币;它将跳过您期望的换行符,然后读取下一个非空格字符。"%f%c"
格式中没有什么意义;它并不能保证你会读取换行符(并且你不会检查它是否存在)。
另外,正如其他人也指出的那样:
if ( ( in_currency || out_currency ) != ( '$' || 'Y' || 'E' ) )
没有做你想做的事。由于C的工作方式,!=
的RHS求值为true(因为'$'
不为零),并且除非in_currency
和{{1},否则它的LHS计算结果为真是零,这是非常不可能的(许多人不知道如何在键盘上键入ASCII NUL - 也就是零字节或out_currency
)。
正如我在评论中所说:
原文可能意在表示:_如果
'\0'
不是in_currency
或'$'
或'Y'
,或'E'
不是out_currency
或'$'
或'Y'
中的一个,然后将标记设置为0.
你需要更像
的东西'E'
我看到一个条件的版本写成:
if (( in_currency != '$' && in_currency != 'Y' && in_currency != 'E') ||
(out_currency != '$' && out_currency != 'Y' && out_currency != 'E'))
flag = 0;
这不能正常工作。想一想:假设if (( in_currency != '$' || in_currency != 'Y' || in_currency != 'E' ) ||
(out_currency != '$' || out_currency != 'Y' || out_currency != 'E' ))
flag = 0;
是Y(日元)。术语in_currency
将为真(因为值为Y),因此整体条件为真(未评估任何其他项),in_currency != '$'
将设置为零。如果您flag
分隔&&
个字词,则in_currency
将为真,但in_currency != '$'
将为false,因此条件的in_currency != 'Y'
部分将为false - 这很好,因为货币代码有效。然后它将继续评估(in_currency != '$' && in_currency != 'Y' && in_currency != 'E')
项(也使用out_currency
),并且只要out_currency值正确,也会通过。
请注意,将&&
形式与同一个变量(a != v1 || a != v2)
与两个不同的值a
和v1
进行比较的条件始终是真实的。请注意,这个领域的常用英语用法有点滑;你必须非常小心和挑剔才能使条件正确。您还需要了解De Morgan的定理(q.v。)。
您可以使用代码选择其他问题。例如,您的错误消息不是很有用。在您获得足够的信息以确定其无效后,您需要用户继续输入数据。您需要确保您的代码处理用户选择从欧元转换为欧元的情况(或者更常见的是,输入相同的货币代码两次)。
编写好的代码部分是为了理解用户如何破坏你的最佳意图,并在问题发生之前解决问题。