int getline(char s[], int lim)
{
int c, i;
for(i=0; i<lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
s[i] = c;
if(c=='\n'){
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
这个例子来自K&amp; R book on C,第1.9章关于数组。我不明白为什么我们必须在++i
声明中包含if
?在外面写它应该做同样的工作。
if(c=='\n')
s[i] = c;
++i;
s[i] = '\0'
return 0;
}
如果按照预期包含i
程序,但在第二种情况下(我认为应该做同样的工作,这就是我编辑那部分的原因)它没有。我通过调试器运行它并观察i
,在这两种情况下都正确计算并返回。但如果不接受++i
,程序仍然无效。我没有从printf
语句中获取我的打印,而Ctrl + D只是在终端或XTerm中无法工作(彻底的CodeBlocks)我无法弄清楚原因。有什么提示吗?我错过了一些合乎逻辑的步骤吗这是一个完整的代码:
//Program that reads lines and prints the longest
/*----------------------------------------------------------------------------*/
#include <stdio.h>
#define MAXLINE 1000
int getline(char currentline[], int maxlinelenght);
void copy(char saveto[], char copyfrom[]);
/*----------------------------------------------------------------------------*/
int main(void)
{
int len, max;
char line[MAXLINE], longest[MAXLINE];
max = 0;
while( (len = getline(line, MAXLINE)) > 0 )
if(len > max){
max = len;
copy(longest, line);
}
if(max > 0)
printf("StrLength:%d\nString:%s", max, longest);
return 0;
}
/*----------------------------------------------------------------------------*/
int getline(char s[], int lim)
{
int c, i;
for(i=0; i<lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
s[i] = c;
if(c=='\n'){
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
/*----------------------------------------------------------------------------*/
void copy(char to[], char from[])
{
int i;
i = 0;
while( (to[i]=from[i]) != '\0')
++i;
}
/*----------------------------------------------------------------------------*/
答案 0 :(得分:2)
线路
if(c == '\n')
相当于
if(c != EOF)
这有助于解释为什么会发生拥抱吗?
答案 1 :(得分:1)
++i
位于if
语句中,因为如果我们不将i
字符放在当前索引中,我们不想增加\n
;这将导致在输入的最后一个字符和字符串末尾的\0
之间留下一个索引。
答案 2 :(得分:1)
那里有一个逻辑:
if(c=='\n'){
s[i] = c;
++i;
}
这意味着只有当您阅读其他换行符时,才需要再增加i
一个,以便为\0
字符留出空间。如果您将++i
放在if
块之外。这意味着即使没有i
,也会1
总是增加newline input
,在这种情况下,因为i
已经for loop
增加了\0
已经是++i
的空间,因此,i
将再次出错。您可以打印{{1}}的值并查看其工作原理。
答案 3 :(得分:1)
i
指定的索引是当该行没有更多输入时应该放置终止空值的位置。索引i
之前的位置包含字符串中的最后一个有效字符。
请记住,从stdin
读取数据的循环可能会因读取\n
字符以外的原因而终止。
如果你有这个结构:
if(c=='\n')
s[i] = c;
++i;
然后,如果从stdin
读取的最后一个字符不是换行符,则将索引递增一,而不将任何内容写入由预递增值i
指定的位置。您可以有效地在结果中添加未指定的字符。
更糟(?),如果for
循环由于i<lim-1
条件而终止,则最终会在指定的数组末尾之后写入终止空字符,从而导致未定义的行为(内存损坏) )。
答案 4 :(得分:0)
由于3个条件,for循环可以退出 1.读取字符限制达到或EOF遇到 2.遇到新线
对于第一种情况我们需要将Null存储到字符串s中,因为我指向下一个有效字符读取的位置,所以不需要增加i。 但是对于第二种情况,当我指向下一个有效字符读取的位置时,我们现在将换行存储在该位置,然后递增i以存储NULL字符。
这就是为什么我们需要在第二种情况下增加i而不是第一种情况。
if(c=='\n'){
s[i] = c;
++i;
}