我正在使用Xcode 8学习C,并且编译器在执行while或for循环后不运行任何代码。这是一个错误吗?我该如何解决?
在下面提供的示例中,printf("code executed after while-loop");
永远不会执行
#include <stdio.h>
int getTheLine(char string[]);
int getTheLine(char string[]) {
char character;
int index;
index = 0;
while ((character = getchar()) >= EOF) {
string[index] = character;
++index;
}
printf("code executed after while-loop");
return index;
}
int main(int argc, const char * argv[]) {
char string[100];
int length = getTheLine(string);
printf("length %d\n", length);
return 0;
}
答案 0 :(得分:2)
int
会返回char
而不是EOF
,并且应该使用!=
运算符代替>=
与...
int character; // int instead of char
int index;
index = 0;
while ((character = getchar()) != EOF) { // != instead of >=
...
进行比较操作
THREE.Sprite()
答案 1 :(得分:2)
这是>= EOF
,它将使条件始终为true
。原因是getchar()
的“有效”结果将是正整数,而像文件结尾的“无效”结果将是EOF
,这是负数(参见{ {3}}):
EOF ... int类型和负值
的整数常量表达式
因此,来自getchar
的任何有效结果都是>EOF
,而文件结尾结果将是==EOF
,这样>= EOF
将始终匹配。
改为写!= EOF
。
进一步注意,不要通过字符串终止字符'\0'
来终止字符串,这样使用string
就像字符串一样(例如在printf("%s",string))
中会产生未定义的行为(崩溃或其他可能不需要的东西)。
所以至少写一下:
while ((character = getchar()) != EOF) {
string[index] = character;
++index;
}
string[index]='\0';
然后仍有一个问题,你可能写出界限,例如如果一个人在你的例子中输入超过100个字符。但是检查这个问题现在已经超出了实际问题,这是关于无限循环的。
答案 2 :(得分:2)
符号常量EOF
是整数常量,类型为int
。它(通常)定义为宏-1
。
问题是,作为(32位)-1
的值int
具有值0xffffffff
和具有相同值的(8位)char
将是0xff
。这两个值并不相等。这反过来意味着你的循环条件永远不会为假,导致无限循环。
此问题的解决方案是所有读取字符的标准函数都将其返回为int
。这意味着您的变量character
也必须属于该类型。
重要说明:如果普通char
是有符号或无符号类型,则它是编译器实现细节。如果已签名,则在比较中提升int
值时,与char
的比较将导致签名扩展。这意味着值signed char
的{{1}}将扩展为0xff
值int
。这意味着如果0xffffffff
已签名,那么比较就可以了。
这意味着您的编译char
为char
。因此,升级到unsigned char
后的unsigned char
值0xff
将为int
。
至于为什么值0x000000ff
变为-1
是因为负数通常在计算机上表示,并带有two's complement。
您的代码中还有另外几个缺陷。
第一个是因为循环是无限的,你将 way 超出0xffffffff
数组的范围,导致未定义的行为(并且可能早晚崩溃)。解决方法是添加一个条件以确保string
永远不会达到index
(在数组的特定情况下,应该真的作为参数传递)。
第二个问题是,如果您打算将100
数组用作实际字符串,则需要终止它。 C中的字符串实际上称为 null 已终止字符串。该终结符是字符string
(等于整数'\0'
),需要放在要传递给处理此类字符串的标准函数的每个字符串的末尾。使用此终结符意味着0
个字符数组中只能包含99个字符,以便能够适应终结符。这对解决上述问题有影响。至于如何添加终结符,只需在循环后执行100
(如果string[index] = '\0';
当然在范围内)。