在C中while-或for-loop之后没有代码执行

时间:2017-06-14 08:22:21

标签: c xcode8

我正在使用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;
}

3 个答案:

答案 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}}将扩展为0xffint。这意味着如果0xffffffff已签名,那么比较就可以了。

这意味着您的编译charchar。因此,升级到unsigned char后的unsigned char0xff将为int

至于为什么0x000000ff变为-1是因为负数通常在计算机上表示,并带有two's complement

您的代码中还有另外几个缺陷。

第一个是因为循环是无限的,你将 way 超出0xffffffff数组的范围,导致未定义的行为(并且可能早晚崩溃)。解决方法是添加一个条件以确保string永远不会达到index(在数组的特定情况下,应该真的作为参数传递)。

第二个问题是,如果您打算将100数组用作实际字符串,则需要终止它。 C中的字符串实际上称为 null 已终止字符串。该终结符是字符string(等于整数'\0'),需要放在要传递给处理此类字符串的标准函数的每个字符串的末尾。使用此终结符意味着0个字符数组中只能包含99个字符,以便能够适应终结符。这对解决上述问题有影响。至于如何添加终结符,只需在循环后执行100(如果string[index] = '\0';当然在范围内)。