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

C程序中'\0'位置错误导致输出多余点,测试用例失败

解决C代码输出多余小数点的问题

我的C代码在处理数字字面量时会输出多余的小数点,导致无法通过测试用例。我知道问题出在字符串终止符'\0'的位置不正确,以下是我的代码:

else if (isdigit(c))
{
    value[0] = (char)c;
    c = fgetc(input);
    int count = 0;
    int index = 1;
    bool isRealNumber = false;

    while (isdigit(c) || c == '.') 
    {
        if (c == '.') 
        {
            isRealNumber = true;
            c = fgetc(input);

            if (c == '.')
            {
                value[index] = '.';
                index++; 
                value[index + 1] = '\0';
                c = ungetc(c, input);
                break;
            }
            else
            {
                value[index] = '.';
                index++;
                value[index + 1] = '\0';
            }
        }
        value[index] = (char)c;
        c = fgetc(input);
        count += 1;
        index += 1;
    }
    c = ungetc(c, input);

    if (isRealNumber)
        T.id = SQL_REAL_LITERAL;
    else
        T.id = SQL_INT_LITERAL;

    T.line = *lineNumber;
    T.col = *colNumber;

    *colNumber = *colNumber + count + 1;

    value[index] = '\0';

    return T;
}

我尝试过提前设置'\0',但并未解决问题。


问题分析

  1. 处理小数点时提前设置value[index + 1] = '\0',但后续代码仍会执行赋值和index递增操作,导致终止符位置被覆盖或错位。
  2. 遇到小数点后,无论下一个字符是否为数字,都会强制写入小数点,后续还会把非数字字符(比如第二个小数点)写入数组,加上终止符位置错误,最终输出多余的点。

修正后的代码

// 先定义value数组的最大长度,根据实际需求调整
#define MAX_VALUE_LENGTH 100

else if (isdigit(c))
{
    value[0] = (char)c;
    c = fgetc(input);
    int count = 0;
    int index = 1;
    bool isRealNumber = false;
    bool dotHandled = false; // 标记是否已处理过小数点

    // 限制index避免数组越界,同时确保一个数字最多处理一个小数点
    while ((isdigit(c) || (c == '.' && !dotHandled)) && index < MAX_VALUE_LENGTH - 1)
    {
        if (c == '.') 
        {
            dotHandled = true;
            // 先读取下一个字符,判断是否是有效实数的一部分
            char nextChar = fgetc(input);
            if (isdigit(nextChar))
            {
                isRealNumber = true;
                value[index] = '.';
                index++;
                // 把数字写回输入流,让后续循环处理
                c = ungetc(nextChar, input);
            }
            else
            {
                // 这个小数点不是实数的一部分,回退并终止循环
                c = ungetc(nextChar, input);
                break;
            }
        }
        // 只写入数字字符
        if (isdigit(c))
        {
            value[index] = (char)c;
            c = fgetc(input);
            count++;
            index++;
        }
    }
    c = ungetc(c, input);

    // 确保终止符放在正确位置,覆盖所有错误的提前设置
    value[index] = '\0';

    T.id = isRealNumber ? SQL_REAL_LITERAL : SQL_INT_LITERAL;
    T.line = *lineNumber;
    T.col = *colNumber;

    *colNumber += count + 1;

    return T;
}

关键修改点

  • 新增dotHandled标记,避免一个数字字面量出现多个小数点。
  • 处理小数点时先检查下一个字符是否为数字,只有后续是数字时才保留小数点并标记为实数,否则回退输入流,不写入无效小数点。
  • 限制index不超过数组最大长度减一,防止数组越界导致的未定义行为。
  • 仅将数字字符写入value数组,避免非数字字符混入。
  • 将value[index] = '\0'提前到类型判断前,确保无论循环如何结束,终止符都在正确位置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 02:35:48