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

C语言编程中strcmp用法是否有误?仅识别Large输入问题排查

问题描述

实现C语言饮品规格输入校验逻辑:用户输入内容不属于Small/small/Large/large四个合法值时,持续提示重新输入。实际运行时仅输入Large可通过校验,其余三个合法值均被判定为非法。

问题复现代码
#include <stdio.h>
#include <string.h>
int main()
{
    char drinksize[5];
    do
        {
            printf("\nEnter Drink Size (Small or Large): ");
            scanf("%s", drinksize);
            if(strcmp(drinksize, "Small") == 1 || strcmp(drinksize, "small") == 1 || strcmp(drinksize, "Large") == 1 || strcmp(drinksize, "large") == 1)
            {
                printf("Incorrect item number! Please try again.");
            }
        }
        while (strcmp(drinksize, "Small") == 1 || strcmp(drinksize, "small") == 1 || strcmp(drinksize, "Large") == 1 || strcmp(drinksize, "large") == 1);
}
错误原因

核心问题是strcmp的使用存在两处明显错误,同时附带一个内存安全隐患:

  • 对strcmp返回值规则理解错误
    C标准仅规定strcmp的三类返回结果,没有要求返回固定的1/-1:
    • 两个字符串完全相等时,返回值固定为0
    • 第一个字符串字典序大于第二个字符串时,返回任意正整数(不同编译环境、不同libc实现下可能是1、32或其他正数值,不能依赖返回值等于1做判断)
    • 第一个字符串字典序小于第二个字符串时,返回任意负整数
  • 输入合法性判定逻辑完全写反
    原代码将「和任意一个合法值比较结果等于1」作为非法输入判定条件,完全不符合字符串相等判断逻辑。结合当前环境下strcmp的返回值表现,四个字符串的字典序为Large < Small < large < small:
    • 输入Large时,和四个合法值比较的结果分别为负、负、0、负,没有等于1的返回值,因此被误判为合法,退出循环
    • 输入其余三个合法值时,总会存在和某一个合法值比较返回正整数1的情况,因此被误判为非法,持续循环
  • 缓冲区溢出隐患
    定义的drinksize数组长度仅为5,且scanf("%s")未限制读取长度,用户输入超过4个字符时会越界写入内存,触发未定义行为。
修复后代码

正确逻辑为:输入和四个合法值比较全部不相等时,才判定为非法需要重输,同时增加输入长度限制避免越界:

#include <stdio.h>
#include <string.h>
int main()
{
    // 预留足够数组长度
    char drinksize[16];
    do
    {
        printf("\nEnter Drink Size (Small or Large): ");
        // 限制最大读取长度为15,避免缓冲区溢出
        scanf("%15s", drinksize);
        // 所有合法值均不匹配时提示错误
        if(strcmp(drinksize, "Small") != 0 
            && strcmp(drinksize, "small") != 0 
            && strcmp(drinksize, "Large") != 0 
            && strcmp(drinksize, "large") != 0)
        {
            printf("Incorrect item number! Please try again.\n");
        }
        // 循环条件与错误判定逻辑一致,输入非法则继续循环
    } while (strcmp(drinksize, "Small") != 0 
        && strcmp(drinksize, "small") != 0 
        && strcmp(drinksize, "Large") != 0 
        && strcmp(drinksize, "large") != 0);

    // 后续业务逻辑
    printf("Input valid, drink size: %s\n", drinksize);
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 10:57:27