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

C语言从标准输入读取指定长度字符串的代码优化求助

getString函数优化建议

你的代码目前功能是跑通的,主要问题集中在魔法值零散、逻辑块拆分不清晰、重复计算多、边界处理逻辑藏得太深这几个点,改完好读很多,还能顺便补上几个潜在的逻辑漏洞。

原代码可优化的核心问题

  • 合法长度用lengthOne/lengthTwo/maxLength命名,语义非常模糊,读代码的人没法第一时间反应过来这几个值是「合法输入长度集合」
  • 重复调用strlen(str)计算字符串长度,同一个循环里算好几次,既冗余也打断阅读逻辑
  • 替换换行符、清空输入缓冲区残留内容的逻辑散落在do-while循环里,没有做语义拆分,读的时候要逐行捋才知道每块在干嘛
  • fgets读取长度传maxLength +2的逻辑没有注释,很容易让读代码的人困惑为什么分配了maxLength+1的空间,却要多读2个字节
  • 循环退出条件写得很长,三个长度判断堆在一起,没法一眼看出判断规则
  • malloc的返回值没有做校验,内存使用完也没有释放,虽然习题环境里大概率不会触发问题,但不符合C语言编码规范

优化后的完整代码

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

// 定义合法输入长度的常量,用明确的语义命名
#define VALID_LEN_13 13
#define VALID_LEN_15 15
#define VALID_LEN_16 16
#define BUF_SIZE (VALID_LEN_16 + 2) 
// 缓冲区大小说明:多留2字节,分别存fgets可能读入的换行符、字符串结束符\0,方便判断输入是否超长

/**
 * 读取用户输入,仅返回长度恰好为13/15/16的字符串
 * 返回值为堆上分配的字符串指针,调用方使用后需要手动free释放
 */
char *getString()
{
    char *str = malloc(sizeof(char) * BUF_SIZE);
    if (str == NULL) { // 校验内存分配是否成功
        fprintf(stderr, "内存分配失败\n");
        exit(EXIT_FAILURE);
    }

    size_t input_len = 0;
    do {
        printf("请输入长度为%d、%d或%d的字符串:", VALID_LEN_13, VALID_LEN_15, VALID_LEN_16);
        fgets(str, BUF_SIZE, stdin);

        // 查找并替换fgets读入的末尾换行符
        char *newline_pos = strchr(str, '\n');
        if (newline_pos != NULL) {
            *newline_pos = '\0';
            input_len = newline_pos - str; // 直接通过指针偏移算长度,不用重复遍历计算strlen
        } else {
            input_len = strlen(str);
            // 没读到换行说明输入超过缓冲区长度,清空标准输入里残留的内容,避免影响下次读取
            int ch;
            while ((ch = getchar()) != '\n' && ch != EOF);
        }

    // 明确判断:输入长度不在三个合法值里就继续循环提示输入
    } while (input_len != VALID_LEN_13 && input_len != VALID_LEN_15 && input_len != VALID_LEN_16);

    return str;
}

int main()
{
    char *user_input = getString();
    printf("输入的字符串内容:%s\n", user_input);
    printf("字符串长度为:%zu\n", strlen(user_input));
    free(user_input); // 释放堆内存,避免内存泄漏
    return 0;
}

关键优化点说明

  • 把零散的魔法值全部改成大写宏定义,命名直接对应语义,读代码的时候不用翻前面的变量赋值找对应数值
  • 把原来遍历整个字符串找换行符的逻辑,换成用标准库strchr函数直接定位换行,效率更高,逻辑也更直观
  • 把输入长度提前存在input_len变量里,不用在循环条件、判断逻辑里反复调用strlen做重复计算
  • 把清空输入缓冲区的逻辑和「是否读到换行」的判断绑定在一起,逻辑更顺:只要fgets没读到换行,就说明输入超长有残留,直接清空,比原来判断strlen>maxLength的逻辑更直观,也补上了原代码没处理EOF导致可能死循环的bug
  • 给函数加了标准注释,说明函数功能、返回值注意事项,关键逻辑点加了行内注释,不用靠猜理解代码意图
  • 变量命名全部换成语义明确的名字,比如main函数里原来的string改成user_input,一眼就知道是存用户输入的,删掉了lengthOne这类无意义的命名
  • 补上了malloc返回值校验、使用完内存后free的规范写法

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 05:00:49