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

C语言程序写入二进制文件后最后一行出现多余0的原因排查

问题分析:divided.bin文件最后一行出现多余0的原因

问题场景

以下C语言代码用于读取3行输入,提取每行偶数并倒序写入divided.bin文件:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>

int main()
{
    FILE* number;
    char strings[3][100];
    errno_t err = fopen_s(&number, "number.bin", "wb");
    if (err != 0)
    {
        printf("error open number.bin\n");
        return 1;
    }

    FILE* divided;
    err = fopen_s(&divided, "divided.bin", "wb+");
    if (err != 0)
    {
        printf("error open divided.bin\n");
        return 1;
    }

    printf("Enter 3 lines:\n");

    for (int i = 0; i < 3; i++)
    {
        fgets(strings[i], sizeof(strings[i]), stdin);
        fwrite(strings[i], sizeof(char), strlen(strings[i]), number);
        char* token;
        char* nextToken = NULL;
        token = strtok_s(strings[i], " ", &nextToken);
        int count = 0;
        int numbers[100] = { 0 }; // 初始化数组为0
        while (token != NULL)
        {
            if (atoi(token) % 2 == 0)
            {
                numbers[count] = atoi(token);
                count++;
            }
            token = strtok_s(NULL, " ", &nextToken);
        }
        for (int j = count - 1; j >= 0; j--)
        {
            fprintf(divided, "%d ", numbers[j]);
        }
        fprintf(divided, "\n");
    }

    fseek(divided, 0, SEEK_SET);

    printf("Numbers that are multiples of 2 in reverse order:\n");
    char str[100];
    while (fscanf_s(divided, "%99s", str, (unsigned)_countof(str)) == 1)
    {
        if (strcmp(str, "0") != 0)
        {
            printf("%s ", str);
        }
    }

    fclose(number);
    fclose(divided);

    printf("\nSuccessfully written to file divided\n");

    return 0;
}

输入数据:

12 4 9 5
200 4568 89 8
6 33333 489 725 20 

预期divided.bin内容每行是偶数倒序,但实际输出:

4 12 
8 4568 200 
0 20 6 

最后一行多了个0,原因如下:

原因分析

问题出在fgets的行为和strtok_s的分隔符设置上:

  1. fgets读取输入时,会把每行末尾的换行符\n也一并读入到strings[i]数组中;
  2. 代码中strtok_s仅以空格作为分隔符,当处理第三行输入时,拆分到最后会把换行符\n当成一个独立的token;
  3. atoi("\n")的转换结果是0,而0是偶数,会被存入numbers数组,最终倒序输出时就出现在了第三行的开头。

解决办法

有两种简单的修复方式:

  • 方式一:提前去除换行符
    在fgets读取后,用strcspn定位换行符并替换为字符串结束符:
    fgets(strings[i], sizeof(strings[i]), stdin);
    // 移除末尾的换行符
    strings[i][strcspn(strings[i], "\n")] = '\0';
    
  • 方式二:扩展分隔符集合
    修改strtok_s的分隔符,把换行符也加入其中:
    token = strtok_s(strings[i], " \n", &nextToken);
    
    这样拆分时会自动跳过空格和换行符,不会把\n识别为有效token。

内容的提问来源于stack exchange,提问作者Артем Пед</think_never_used_51bce0c785ca2f68081bfa7d91973934>

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 05:37:43