C语言 既然没有满足所有条件,为什么要执行for循环中的递增步骤?

68de4m5k  于 2023-01-25  发布在  其他
关注(0)|答案(1)|浏览(192)

我正在使用《C编程语言》一书学习C语言,我在第1章中学习了字符数组(第1.9节),这是它提供的getline()函数:

/* getline: read a line into s, return length */
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;
}

以单词"Hi"为例。
在我看来,s[1]应该等于'\n',因为i应该只在所有条件都满足时递增,然而,当c等于'\n'时,for循环退出,并且i应该包含1的值,而不是2的值。
那么,为什么它只在满足3个条件中的2个条件的情况下递增?
我已经尝试过使用前增量操作符和后增量操作符,并在某些代码行中测试了i值。

w8f9ii69

w8f9ii691#

循环变量i在循环体结束时递增。您可以编写for-loop:

for(i = 0; i < lim-1 && (c = getchar()) != EOF && c != '\n'; i++)
    s[i] = c;

作为等效的while-循环:

i = 0;
while(i < lim-1 && (c = getchar()) != EOF && c != '\n') {
    s[i] = c;
    i++;
}

另外,我建议你重命名你的函数,不要与现有的同名函数冲突,考虑交换参数,这样你就可以表达lims变量之间的关系,并且使用size_t代替int,因为负的lim概率是没有意义的:

size_t my_getline(size_t lim, char s[lim]);

i < lim - 1的循环条件是错误的,因为可能在循环后写入2个字节,这将使缓冲区溢出。如果lim <= 0,您将使缓冲区溢出。如果lim < 1,您将有未定义的行为,因为c未初始化。我建议您这样处理循环中的换行符,并且只有在s至少有1个字节的空间时才写入“\0”:

size_t my_getline(size_t lim, char s[lim]) {
    size_t i = 0;
    while(i < lim - 1) {
        int c = getchar();
        if(c == EOF) break;
        s[i++] = c;
        if(c == '\n') break;
    }
    if(lim) s[i] = '\0';
    return i;
}

相关问题