You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

K&R习题1-20:制表符转指定数量空格的代码异常问题

修复K&R习题1-20的制表符转空格代码

我一眼就看出你的代码问题出在哪了——你把制表符直接硬替换成4个空格,但习题要求的是把制表符替换成足够的空格,让光标对齐到下一个制表位(比如当前位置到下一个4的倍数的位置缺几个补几个),另外还有几处小的越界和冗余问题,导致输入This is\ta test.时输出不符合预期。

具体错误点

  • 制表符替换逻辑错误:你没有计算当前位置到下一个制表位的空格数,而是固定补4个。比如This is结束后光标在第7位(索引从0开始),下一个制表位是第8位,这时候只需要补1个空格,而不是4个——这就是你输出不对的核心原因。
  • 数组越界判断不合理:你用index < MAX_SIZE -5来限制空格填充,这个数字完全是拍脑袋的,应该动态判断剩余空间,确保不会超出数组的最大长度(要留位置给终止符\0)。
  • 冗余代码:main函数里的extern char longest[]完全没用,属于多余的代码;getline_里的extern char line[]也没必要,因为line是全局变量,函数可以直接访问。
  • index更新逻辑有漏洞:原代码在填充空格时的循环条件可能导致index计算错误,比如如果数组快满了,x会提前终止,这时候index的更新虽然是对的,但循环条件本身就不对。

修复后的代码

#include <stdio.h>
#define MAX_SIZE 1000
#define TAB_STOP 4

char line[MAX_SIZE];
int getline_(void);

int main() {
    int len;
    while ((len = getline_()) > 0)
        printf("Line: %s", line);
    return 0;
}

int getline_(void) {
    int chr, index;
    int needed_spaces;
    
    // 把index的递增放到循环体内,方便灵活控制
    for (index = 0; index < (MAX_SIZE - 1) && ((chr = getchar()) != EOF) && chr != '\n'; ) {
        if (chr == '\t') {
            // 计算当前位置到下一个制表位需要的空格数
            // 下一个制表位 = ((当前索引 / 制表位宽度) + 1) * 制表位宽度
            needed_spaces = ((index / TAB_STOP) + 1) * TAB_STOP - index;
            
            // 逐字符填充空格,同时确保不越界
            while (needed_spaces > 0 && index < MAX_SIZE - 1) {
                line[index++] = ' ';
                needed_spaces--;
            }
        } else {
            // 普通字符直接存入数组,index自增
            line[index++] = chr;
        }
    }
    
    // 处理换行符,同样要检查越界
    if (chr == '\n' && index < MAX_SIZE - 1) {
        line[index++] = chr;
    }
    
    // 加上字符串终止符
    line[index] = '\0';
    return index;
}

修复关键点解释

  1. 正确计算空格数:通过((index / TAB_STOP) + 1) * TAB_STOP - index精准算出当前位置到下一个制表位需要的空格数,确保对齐正确。比如index=7、TAB_STOP=4时,下一个制表位是8,所以只需要1个空格。
  2. 严格的越界保护:在填充空格和处理换行符时,都检查index是否小于MAX_SIZE -1,保证最后有位置放\0,避免数组溢出。
  3. 简化index管理:把index的递增从for循环的第三个表达式移到循环体内,这样处理制表符时可以灵活控制index的增长,逻辑更清晰。
  4. 清理冗余代码:删掉了没用的extern变量,让代码更简洁。

现在测试输入This is\ta test.,输出会是正确对齐的Line: This is a test.(中间的制表符被替换成1个空格,刚好对齐到下一个制表位)。

内容的提问来源于stack exchange,提问作者Ahmed Mohamed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 18:02:47