执行while或for循环后没有代码执行C
我正在使用Xcode 8学习C,编译器在执行while或for循环后不运行任何代码。这是一个错误?我该如何解决它?执行while或for循环后没有代码执行C
在下面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;
}
getchar
返回int
不是char
,和比较EOF
应与!=
操作者而不是操作者>=
来完成。
...
int character; // int instead of char
int index;
index = 0;
while ((character = getchar()) != EOF) { // != instead of >=
...
我最初编写了像你所建议的代码。同样的问题 –
@CristianLăpuşan你的代码与我的修复应用程序在这里工作很好。你的输入是什么?你的平台是什么?请记住:在Linux上,EOF使用Ctrl + D完成,在Windows上使用Ctrl + Z完成。 –
我正在使用Xcode,macOS Sierra。 –
这是>= EOF
,这将让病情始终true
。其原因是,getchar()
“有效”的结果将是一个正整数,和一个“非有效”导致像文件结束-将EOF
,其是负(参见getchar()):
EOF ... int类型和负值
因此的整数常量表达式,从getchar
任何有效的结果将是>EOF
,而结束文件的结果将是==EOF
,使得>= EOF
将总是匹配。
改为写!= EOF
。
此外,值得注意的是你不串终止字符'\0'
,使得在使用string
像一个字符串(例如,将产生不确定的行为(崩溃或别的东西,可能不需要)终止您的字符串。 所以写至少:
while ((character = getchar()) != EOF) {
string[index] = character;
++index;
}
string[index]='\0';
然后还有,你可以写出界,例如如果一个人在你的例子进入100多个字符,但检查这现在是超出了实际问题,这是对的问题。无限循环
如果我提前退出函数,说我在循环后立即插入“if(character == 47){return index;}”,那么代码运行正常 –
@CristianLăpuşan:我想你的意思是“内循环”,因为你的循环永远不会结束;所以“while循环后执行的代码”永远不会被打印,对吧? –
符号常数EOF
是整数常数,类型为int
。它(通常)被定义为一个宏,如-1
。
的问题是,作为(32位)的值-1
int
具有值0xffffffff
和作为(8位)char
相同的值将是0xff
。这两个值不相等。这反过来意味着你的循环条件将永不为假,导致无限循环。
解决此问题的方法是,所有读取字符的标准函数都将其作为int
返回。这意味着您的变量character
也需要具有该类型。
重要注意事项:如果普通char
是有符号或无符号类型,这是一个编译器实现细节。如果它是有符号的,那么与int
的比较将导致符号扩展当char
值在比较中被提升时。这意味着signed char
与值0xff
将扩展到int
值0xffffffff
。这意味着如果char
已签名,那么比较就会起作用。
这意味着您的编译有char
为unsigned char
。所以推广到int
后unsigned char
值0xff
将为0x000000ff
。
至于为什么值-1
变得0xffffffff
是因为如何负数的计算机上通常表示,其中一种叫two's complement。
您的代码中还有另外两个缺陷。
首先是因为循环是无限的,你会去方式出string
阵列的界限,导致未定义行为(以及可能的崩溃迟早)。解决方法是添加一个条件,以确保index
永远不会达到100
(在数组的特定情况下,应该真正作为参数传递)。
第二个问题是,如果你打算用string
数组作为实际字符串,你需要终止它。 C中的字符串实际上被称为null 终止字符串。该终结符是字符'\0'
(等于整数0
),并且需要放在每个要传递给处理此类字符串的标准函数的字符串的末尾。拥有这个终结符意味着一个100
字符数组只能有99个字符,以便能够匹配终结符。这对解决上述问题具有影响。至于如何添加终止符,只需在循环后执行string[index] = '\0';
(如果index
在当然范围内)。
它不工作.. –
@CristianLăpuşan* *什么*“不工作”?你是否将'character'的类型改为'int'?你在做别的事情吗?你是否尝试过在调试器中的代码?你试过在循环后面添加一个(尾随)换行符到你打印的字符串(因为输出到'stdout'是默认的行缓冲)? –
Upvoted为你带来的所有细节。但只是为了理解:在((char)-1 ==(int)-1'中不会整体提升)确保'(char)-1'实际上是扩展的到'0xffffffff'? –
您可以开始向我们展示您的代码。 –
编译器不应该运行任何代码。它应该将[*翻译单元*](https://en.wikipedia.org/wiki/Translation_unit_(programming))编译成目标文件,然后将其链接到可执行文件中。 IDE然后可以启动一个进程来运行可执行文件。 –
更重要的是,请[阅读关于如何提出好问题](http://stackoverflow.com/help/how-to-ask)并学习如何创建[最小,完整和可验证示例](http ://stackoverflow.com/help/mcve)。 –