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] = '
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;
}
This example is from K&R book on C, chapter 1.9 on arrays. What I do not understand is why do we have to embrace ++i inside if statement? Writing it outside should do the same work.
这个例子来自K&R book on C,第1.9章关于数组。我不明白为什么我们必须在if语句中包含++ i?在外面写它应该做同样的工作。
if(c=='\n')
s[i] = c;
++i;
s[i] = '\0'
return 0;
}
In case of embracing i program works as intended, but on the second case(which in my opinion should do the same work and this is why I edited that part) it doesn't. I ran it through debugger and watched i which in both cases was correctly calculated and returned. But program still won't work without embracing ++i. I don't get my print from printf statement, and Ctrl+D just won't work in terminal or XTerm(thorough CodeBlocks) I can't figure out why. Any hint please? Am I missing some logical step? Here is a complete code:
如果我拥有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;
}
/*----------------------------------------------------------------------------*/
5 个解决方案
#1
2
The line
if(c == '\n') is equivalent to
if(c != EOF)
if(c =='\ n')的行等于if(c!= EOF)
Does that help explain why the embracing occurs?
这有助于解释为什么会发生拥抱吗?
#2
1
There is a logic there:
那里有一个逻辑:
if(c=='\n'){
s[i] = c;
++i;
}
It means only if you read an additional newline, you need to increment i one more in order to keep space for the \0 character. If you put ++i outside the if block. it means that it will always increase i by 1 even there is no newline input, in this case, since i is already incremented in the for loop , there is already space for \0, therefore, ++i again will be wrong. You can print the value of i and see how it works.
这意味着只有当你读取一个额外的换行符时,你需要再增加一个,以便为\ 0字符保留空间。如果你把++ i放在if块之外。它意味着即使没有新行输入也会一直增加i,在这种情况下,由于i已经在for循环中递增,因此已经有空间用于\ 0,因此,++我将再次出错。您可以打印i的值并查看其工作原理。
#3
1
The index specified by i is the location where the terminating null should be placed when there is no more input for the line. The location just before the index i contains the last valid character in the string.
i指定的索引是当行没有更多输入时应该放置终止空值的位置。索引之前的位置i包含字符串中的最后一个有效字符。
Keep in mind that the loop that reads data from stdin can terminate for reasons other than reading a \n character.
请记住,从stdin读取数据的循环可能因读取\ n字符以外的原因而终止。
If you had this construct:
如果你有这个结构:
if(c=='\n')
s[i] = c;
++i;
then if the last character read from stdin wasn't a newline you would increment the index by one without writing anything into the location specified by the pre-incremented value of i. You would be effectively adding an unspecified character to the result.
然后,如果从stdin读取的最后一个字符不是换行符,则将索引增加1而不将任何内容写入由i的预递增值指定的位置。您可以有效地将未指定的字符添加到结果中。
Worse(?), if the for loop terminated because of the i<lim-1 condition you would end up writing the terminating null character after the specified end of the array, resulting in undefined behavior (memory corruption).
更糟糕的是(?),如果for循环由于i
< p="">
<>
#4
1
The ++i is inside the if statement because we do not want to increment i if we are not placing the \n character in the current index; that would result in leaving an index in between the last character of the input and the \0 at the end of the character string.
++ i在if语句中,因为如果我们不将\ n字符放在当前索引中,我们不想增加i;这将导致在输入的最后一个字符和字符串末尾的\ 0之间留下一个索引。
#5
0
For loop can exit due to 3 conditions 1. reading char limit reached or EOF encountered 2. New Line encountered
对于循环可以退出由于3个条件1.读取char限制达到或EOF遇到2.遇到新行
For first Case We need to store Null into string s , as i points to next position to last valid character read so no need to increment i. But for second case , as i points to next position to last valid character read , we now store newline at that position then increment i for storing NULL character.
对于第一种情况我们需要将Null存储到字符串s中,因为我指向下一个有效字符读取的位置,因此不需要增加i。但是对于第二种情况,当我指向下一个有效字符读取的位置时,我们现在将换行存储在该位置然后递增i以存储NULL字符。
Thats why we need to increment i in 2nd case not in 1st case.
这就是为什么我们需要在第二种情况下增加i而不是在第一种情况下。
if(c=='\n'){
s[i] = c;
++i;
}
';
return i;
}
int getline(char s[], int lim)
{
int c, i;