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

C语言中限制二维数组字符串输入为大写的问题排查

C语言限制输入全大写学生姓名时循环异常的问题分析与解决

问题根源分析

第一段代码的核心错误

  • 未初始化数组导致循环逻辑混乱:内层for循环的条件j <= strlen(Name[i]) - 1中,Name[i]初始为未赋值的随机内存,strlen(Name[i])结果完全不可预测,要么直接跳过循环,要么进入后j的取值毫无逻辑。
  • fflush(stdin)的未定义行为:C标准明确fflush仅对输出流有效,用它刷新输入流属于未定义行为,会引发输入处理的异常问题。
  • 仅检查单个字符而非全字符串:do-while循环只验证Name[i][j]这一个字符,没有遍历整个输入字符串,无法确保所有字符都是大写。
  • 未处理fgets读取的换行符:fgets会把用户输入的回车(\n)存入字符串,而\n不在A-Z范围内,导致循环永远无法退出。

第二段代码的核心错误

内层for循环的条件j <= Name[i][j] != '\0'逻辑完全错误:

  • Name[i][j] != '\0'的结果是布尔值(0或1),条件等价于j <= 0或j <= 1,完全无法实现遍历字符串的目的。
  • 同样存在Name[i]未初始化的问题,初始值随机,进一步加剧逻辑混乱。

解决方法(无指针/函数版本)

针对需求,我们需要:

  • 清除scanf留下的输入缓冲区换行符,避免第一个fgets读取空行。
  • 对每个学生,循环读取输入,直到整个字符串的所有字符都是大写字母(若允许姓名包含空格,可调整检查逻辑)。
  • 去掉fgets读取的换行符,避免干扰验证。

修正后的完整代码

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

int main() {
    int number_ofstudents, i, j;
    char Name[100][20];
    int is_valid;

    do {
        printf("Enter number of students \n");
        scanf("%i", &number_ofstudents);
        // 清除scanf留下的换行符,避免影响后续fgets
        getchar();
    } while ((number_ofstudents < 1) || (number_ofstudents > 100)); // 学生数不能为0,调整条件

    for (i = 0; i < number_ofstudents; i++) {
        do {
            is_valid = 1; // 默认输入有效
            printf("Enter the name of student number %i in uppercase \n", i + 1);
            fgets(Name[i], 20, stdin);

            // 去掉fgets读取的换行符
            size_t len = strlen(Name[i]);
            if (len > 0 && Name[i][len-1] == '\n') {
                Name[i][len-1] = '\0';
            }

            // 遍历每个字符检查是否为大写字母
            for (j = 0; Name[i][j] != '\0'; j++) {
                // 如果允许姓名包含空格,可添加条件:&& Name[i][j] != ' '
                if (Name[i][j] < 'A' || Name[i][j] > 'Z') {
                    is_valid = 0;
                    break; // 只要有一个字符不符合,直接退出检查
                }
            }

            if (!is_valid) {
                printf("Invalid input! Please enter only uppercase letters.\n");
            }
        } while (!is_valid); // 输入无效则重新提示
    }

    // 可选:输出验证后的姓名
    printf("\nAll valid student names:\n");
    for (i = 0; i < number_ofstudents; i++) {
        printf("Student %i: %s\n", i+1, Name[i]);
    }

    return 0;
}

关键调整说明

  1. 清除scanf后的换行符:用getchar()读取scanf留在输入缓冲区的\n,确保后续fgets能正常读取用户输入。
  2. 验证整个字符串:通过内层for循环遍历输入的每个字符,只要有一个字符不是大写字母,就标记输入无效。
  3. 处理fgets的换行符:检查字符串末尾的\n并替换为\0,避免这个非大写字符导致验证失败。
  4. 合理的循环逻辑:用is_valid标记输入是否有效,外层do-while循环控制重新输入,直到输入符合要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 15:51:03