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',但并未解决问题。
问题分析
- 处理小数点时提前设置
value[index + 1] = '\0',但后续代码仍会执行赋值和index递增操作,导致终止符位置被覆盖或错位。 - 遇到小数点后,无论下一个字符是否为数字,都会强制写入小数点,后续还会把非数字字符(比如第二个小数点)写入数组,加上终止符位置错误,最终输出多余的点。
修正后的代码
// 先定义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
相关产品推荐
相关产品推荐

