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

C语言读取固定16字符行WAIT/NOWAIT指令文件的实现问题

题目要求的语义澄清

题目中提到的每行长度为16字符(包含行尾换行符),是对文件存储结构的硬性约定:

  • 每一行从行首到行尾换行符\n的总字节数固定为16,不是要求代码端主动补全空格适配短行。
  • 合法行的组成逻辑是:WAIT/NOWAIT 指令内容 + 填充空格 + 换行符,凑满16字节总长度,确保程序可以按固定偏移量(0、16、32...)快速定位每一行的起始位置。
  • 你遇到的测试文件未补全空格的情况,属于测试用例的非标准场景,代码需要做兼容,不能因为行尾提前出现换行就解析错位。
现有代码的核心问题

你目前的逻辑之所以跨行解析,根源是:

  • 硬编码每次固定读取16字节内容,完全没有识别内容里的换行符边界。当测试文件的行实际长度小于16字节(没有补空格)时,read系统调用会一次性把当前行+下一行的开头内容一起读到缓冲区里,直接喂给sscanf就会出现内容错位。
  • 没有对解析过程做边界保护,裸用%s格式的sscanf存在缓冲区溢出风险。
  • 遗漏了文件描述符的关闭操作,存在资源泄漏。
可直接运行的调整方案

按照定长块读取+换行符边界截断的逻辑修改,既可以兼容标准的16字节定长行文件,也可以正确解析未补全空格的短行测试文件,修改要点:

  • 每次固定从文件读取16字节(匹配题目约定的行长)
  • 读取完成后立刻定位缓冲区里的第一个换行符,将其作为当前行的结束位置,替换为字符串结束符,从根源上避免把下一行的内容带入解析
  • 给sscanf增加长度限制,防止缓冲区溢出
  • 补充文件描述符的关闭操作

修改后的核心循环代码:

#define EXPECTED_LINE_LEN 16 // 严格匹配题目约定的含换行的行长
char read_buf[EXPECTED_LINE_LEN + 1]; // 多预留1字节位置放字符串结束符

while (1) {
    ssize_t read_count = read(fd, read_buf, EXPECTED_LINE_LEN);
    // 读到文件末尾或者发生读错误时退出循环
    if (read_count <= 0) break;
    read_buf[read_count] = '\0'; // 无论实际读了多少字节,先补字符串结束符

    // 定位当前读块内的第一个换行符,作为真实行边界
    char *line_break = strchr(read_buf, '\n');
    if (line_break) {
        *line_break = '\0'; // 将换行符替换为结束符,截断行尾的填充/后续行内容
    }

    char type[16], cmd[16];
    // 带长度限制的sscanf,避免越界
    int parse_status = sscanf(read_buf, "%15s %15s", type, cmd);
    if (parse_status != 2) {
        fprintf(stderr, "行格式非法: %s\n", read_buf);
        close(fd);
        exit(4);
    }
    printf("type=%s; command=%s;\n", type, cmd);
}
close(fd);
兼容效果说明
  • 当遇到严格符合要求的16字节定长行(补了空格的版本):换行符位于第16字节位置,截断后不影响sscanf正常识别WAIT/NOWAIT和对应的命令内容
  • 当遇到未补全空格的短行测试文件:换行符提前出现在读块的靠前位置,截断后只会解析当前行的内容,不会跨行读取下一行的数据
  • 自动跳过行中间的多余空格,不会因为填充字符干扰解析结果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.22 08:06:09