K&R练习2-2要求我们使用&&或||重写以下for loop w/out
for(i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; i++)
s[i] = c;首先想到的就是简单地使用一些if语句。注意:代码只是使用getchar()获取用户输入,并将其打印为一个完整的句子。
#include <stdio.h>
#define MAXLINE 1000
int main()
{
char s[MAXLINE];
int lim = MAXLINE;
int i, c;
for (i = 0; i < lim-1;)
{
c = getchar();
if (c != '\n')
{
s[i] = c;
i++;
}
else if (c != EOF)
{
s[i] = c;
i++;
}
else
{
s[i] = '\0';
}
}
printf("%s\n", s);
}当我执行这个命令时,它可以工作,但是我得到了一堆??在终端中,我认为它们与我指定的数组大小的其余部分相关(注意:使用1000的数组是基于K&R示例)。我认为在else上添加一个'\0‘只会改变char数组,以匹配句子的大小。我得到的输出是:
Alexanders-MacBook-Air:coding alexanderroan$ clang exercise2-2.c
Alexanders-MacBook-Air:coding alexanderroan$ ./a.out
this is a test
^D
this is a test
????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
Alexanders-MacBook-Air:coding alexanderroan$ 对如何调整这个有什么建议吗?
发布于 2019-12-02 11:10:04
错误的if()逻辑
尝试替换
for(i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; i++)
s[i] = c;使用
for(i = 0; i < lim - 1; i++) {
c = getchar();
if (c == EOF) {
break;
}
if (c == '\n') {
break;
}
s[i] = c;
}发布于 2019-12-02 15:41:23
您的方法不起作用,因为它设置s[i]并在遇到换行符或EOF时递增i,而不是终止,
有各种不正当的方法可以做到这一点。
一种方法是在逻辑表达式中使用零为假,非零为真的事实。
for (i = 0; i < lim - 1; ++i)
{
c = getchar();
if ((c != EOF) * (c != '\n'))
s[i] = c;
else
i = lim; /* Terminate loop since we have read EOF or '\n' */
}这是因为,两个组件表达式(c != EOF和c != '\n')都给出了零(假)或非零(真)的结果。如果两者都为真(非零),则将它们相乘只会得到真(非零)结果。
注意:不可能将if转换为if ( ((c = getchar()) != EOF) * (c != '\n')),因为* (乘法)不会从左到右计算操作数,也不会像&&或||那样执行快捷方式。
此外,本练习还演示了使用逻辑运算符(&&或||)的替代方法不一定会提供更具可读性的代码。
另一种可能可读性更差的选择是
for (i = 0; i < lim - 1; ++i)
{
c = getchar();
((c != EOF) * (c != '\n')) ? (s[i] = c) : (i = lim);
}发布于 2021-08-04 14:27:44
对于那些正在寻找非if语句解决方案的人--
因为关系运算符返回1或0。您只需确保每个条件都返回1。因此,如果有3个条件...
发自:
for(i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; i++)
s[i] = c;至:
for(i = 0; (i < lim - 1) + ((c = getchar()) != EOF) + (c != '\n') == 3; i++)
s[i] = c;https://stackoverflow.com/questions/59131973
复制相似问题