我正在编写一个简单的代码,该代码将读取一系列字符,这些字符将在读取'\ n'字符/输入enter后终止。该代码也只能读取最多50个字符。但是,我在编译时收到错误,分段错误。我不确定为什么尽管使用'\ n'字符,循环仍未结束。
#include <stdio.h>
#include <ctype.h>
#define MAX 50
int main(void){
char str[MAX] = "0"; //initialise 1st char for the loop
int i;
printf("Enter your sentence, at most 50 character: \n");
for(i = 0; str[i] != '\n'; i++){ //terminates upon \n
str[i] = getchar();
putchar(str[i]);
}
return 0;
}
但是,我尝试将循环条件移入循环本身,并使用if-break组合,它可以完美地工作。
#include <stdio.h>
#include <ctype.h>
#define MAX 50
int main(void){
char str[MAX] = "0"; //initialise 1st char for the loop
int i;
printf("Enter your sentence, at most 50 character: \n");
for(i = 0;; i++){ //terminates upon \n
str[i] = getchar();
putchar(str[i]);
if(str[i] == '\n')
break;
}
return 0;
}
任何专业人士都可以向我解释为什么会这样,我该如何纠正?在此先多谢! :)
已解决。我正在检查数组中的错误元素。大声笑。
答案 0 :(得分:1)
了解for
循环的工作原理。
The
for(expr1; expr2; expr3) // lack of expr2 means 'forever'
instr;
等同于
expr1;
while(expr2) // expr2 is replaced with 'true' if empty
{
instr;
expr3;
}
所以就您而言
for(i = 0; str[i] != '\n'; i++)
测试str[i] != '\n'
是在增量i++
之后计算的,因此它测试数组的错误元素–一个过去刚刚读过的那个!
此外,您无需检查输入数据的长度,因此,如果输入的行多于50个字符,则循环将尝试存储行的尾部在声明的数组的末尾,将触发未定义行为。
编辑
满足两个条件的简单方法是同时进行两个测试:
char str[MAX];
int i;
// print the actual value of defined maximum
printf("Enter your sentence, at most %d character: \n", MAX);
for(i = 0; i < MAX; i++){ // test the length
str[i] = getchar();
if(str[i] == '\n') // test the input char
break;
putchar(str[i]);
}
答案 1 :(得分:1)
发生这种情况是因为在str[i] = getchar();
之后的第一种情况下,i++
语句在条件str[i] != '\n';
阻塞之前执行。因此,您的第一个代码中的检查失败。
尝试修改后的for-loop
:-
for(i = 0; (str[i] = getchar()) != '\n'; i++){ //Here checking happens while reading itself.
putchar(str[i]);
}
请记住,在执行body of
for-loop
之后,控制流将跳回到increment statement
而不是condition-cheking
。