阅读背景:

在代码的一部分中包含/不包含++ i。 K&R最长线的例子

来源:互联网 
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;



你的当前访问异常,请进行认证后继续阅读剩余内容。

分享到: