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

C语言特定格式输入问题排查及代码优化咨询

C语言读取{1,2,3}格式输入的问题与优化建议

问题描述

需要实现读取{1,2,3,4}格式的输入(数字被花括号包裹、逗号分隔),编写的代码在格式正确时运行正常,但输入{2并回车后,程序误判为遇到}而退出循环,代码如下:

znamky = (int*) malloc (n * sizeof(int)); // I allocate memory here
if (znamky == NULL)                   
    return EXIT_FAILURE;
printf("Pocty bodu:\n"); 
scanf("%c",&overeni[0]); // here I check if the first character is {; if not I exit program
if (overeni[0]!=zavorka[0]) 
{
    printf("Nespravny vstup.\n");
    return EXIT_FAILURE;
}
while (scanf("%d",&znamky[count])!=EOF) //here I continue loading numbers, and char fight
{                                       //if the character after number is "," i load another 
   if (scanf("%c",&znaminko[0])==1)     //number, if it is "}"I exit the while cycle   
    {                                   // else I exit the program
        if (znaminko[0]==carka[0])  // if equals ","
            {
                printf("sdf\n");
                count++;
                if (count==n) // if I run out of memory I allocate more
                {
                    n = n*2;
                    znamky = (int*) realloc (znamky, n * sizeof(int) + 4);
                }
                continue;
            }
        if (znaminko[0]==zavorka2[0]) // if equals "}"
            count++;
            printf("utikam\n");
            break;
    }
    else 
    {
        printf("Nespravny vstup\n");
        return EXIT_FAILURE;
    }
}

printf("%d ",count); //here I just print length of my array
printArray(znamky,count); 

free(znamky);
return 0;

问题原因

  1. 语法错误导致无条件退出:判断右花括号的if语句没有用{}包裹多语句,只有count++;属于if块,后面的printf("utikam\n"); break;是无条件执行的——不管读取到的字符是不是},都会直接break退出循环。
  2. 未处理空白字符:输入{2并回车后,scanf("%d", ...)读取完数字2,后续的scanf("%c", ...)会读取到换行符(\n),而代码没有处理这种空白字符,导致进入后续逻辑后触发了无条件break。

优化建议

  • 修复语法错误:所有包含多语句的if必须用{}包裹,比如判断右花括号的部分要修改为:
    if (znaminko[0]==zavorka2[0]) {
        count++;
        printf("utikam\n");
        break;
    }
    
  • 跳过空白字符:scanf读取%c时不会自动跳过空白(空格、换行、制表符),要在%c前加空格,让它自动跳过空白,避免读取到干扰字符:
    scanf(" %c",&znaminko[0])
    
  • 安全处理内存分配:
    • realloc的内存计算不需要额外加4,直接用n * sizeof(int)即可,避免内存计算错误;
    • realloc可能失败,要先保存原指针,防止内存泄漏:
      int *temp = realloc(znamky, n * sizeof(int));
      if (temp == NULL) {
          free(znamky);
          printf("Chyba alokace pameti\n");
          return EXIT_FAILURE;
      }
      znamky = temp;
      
  • 变量简化与初始化:
    • 单个字符变量不需要用数组,比如overeni[0]、znaminko[0]可以换成单个char变量,代码更简洁;
    • 确保count初始化为0,zavorka、carka、zavorka2正确赋值(比如char zavorka = '{'),避免未定义行为。
  • 严格输入校验:
    • 读取整数时,判断scanf的返回值是否为1(成功读取一个整数),而不是判断是否不等于EOF——如果输入格式错误(比如字母),scanf会返回0,此时要触发错误处理;
    • 读取完右花括号后,检查是否还有多余输入,避免格式错误被忽略。
  • 简化逻辑结构:可以用更清晰的循环逻辑,先读取{,然后循环读取「数字+逗号」,最后读取},示例:
    // 读取开头的{,跳过可能的空白
    char start;
    scanf(" %c", &start);
    if (start != '{') {
        printf("Nespravny vstup.\n");
        return EXIT_FAILURE;
    }
    
    int count = 0;
    int n = 4; // 初始容量
    int *znamky = malloc(n * sizeof(int));
    if (!znamky) { /* 内存错误处理 */ }
    
    // 读取第一个数字
    if (scanf(" %d", &znamky[count]) != 1) {
        printf("Nespravny vstup.\n");
        free(znamky);
        return EXIT_FAILURE;
    }
    count++;
    
    while (1) {
        char sep;
        scanf(" %c", &sep);
        if (sep == '}') break;
        if (sep != ',') {
            printf("Nespravny vstup.\n");
            free(znamky);
            return EXIT_FAILURE;
        }
        // 扩容检查
        if (count >= n) {
            n *= 2;
            int *temp = realloc(znamky, n * sizeof(int));
            if (!temp) { /* 错误处理 */ }
            znamky = temp;
        }
        // 读取下一个数字
        if (scanf(" %d", &znamky[count]) != 1) {
            printf("Nespravny vstup.\n");
            free(znamky);
            return EXIT_FAILURE;
        }
        count++;
    }
    

内容的提问来源于stack exchange,提问作者Matouš Kovář

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 19:05:29