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

C语言含多变量for循环的程序输入后无输出挂起问题排查

C语言程序无输出挂起问题排查

问题现象

  • 程序预期功能:输入测试用例数量T,随后输入T个URL:
    • 若URL以https开头,直接输出带Case编号的URL
    • 若URL以http开头,在第4位插入s转为https后输出带Case编号的结果
  • 实际异常:加入测试用例循环后,程序输入后无任何输出直接挂起;移除测试用例循环时,含多变量for循环的代码能正常运行;改用单变量循环时程序有输出但不符合预期。

测试代码示例

1. 无测试用例循环(可正常运行)

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

int main()
{   
   // 无测试用例循环时程序可正常输出
    int i = 0; 
    char *s;
    scanf("%s", s);

    if (s[4] == 's') {
        printf("%s\n", s);
    }
    else
    {
        printf("Case %d: ", i + 1);

        int l = strlen(s);
        for (int j = 0, k = 0; j < l; j++, k++)
        {
            if (k == 4)
            {
                printf("s");
                j--;
            }
            else
            {
                // printf("i = %d j = %d\n", i, j);
                printf("%c", s[j]);
            }        
        }
        printf("\n");
    }    
}

2. 加入测试用例循环(无输出挂起)

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

int main()
{
    int T, n;
    scanf("%d", &T);

    for (int i = 0; i < T; i++)
    {
        char *s;        
        scanf("%s", s);

        if (s[4] == 's')
        {
            printf("Case %d: %s\n", i+1, s);
        }
        else
        {
            printf("Case %d: ", i + 1);

            int l = strlen(s);

            for (int j = 0, k = 0; j < l; j++, k++)
            {
                if (k == 4)
                {
                    printf("s");
                    j--;
                }
                else
                {
                    // printf("i = %d j = %d\n", i, j);
                    printf("%c", s[j]);
                }        
            }
            printf("\n");
        }
    }
}

3. 加入测试用例循环+单变量循环(有输出但不符合预期)

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

int main()
{
    int T, n;
    scanf("%d", &T);

    for (int i = 0; i < T; i++)
    {
        char *s;        
        scanf("%s", s);

        if (s[4] == 's')
        {
            printf("Case %d: %s\n", i+1, s);
        }
        else
        {
            printf("Case %d: ", i + 1);

            int l = strlen(s);

            for (int j = 0; j < l; j++)
            {
                if (j == 4)
                {
                    printf("s");
                    // j--;
                }
                else 
                {
                    // printf("i = %d j = %d\n", i, j);
                    printf("%c", s[j]);
                }        
            }
            printf("\n");
        }
    }
}

问题根源分析

这不是C语言的限制,而是代码存在严重的未定义行为错误,核心问题是未初始化的字符指针:

  1. 所有代码中都定义了char *s;但未为其分配内存,也未指向有效的内存区域。scanf("%s", s)会将输入的字符串写入一个随机的内存地址,这属于未定义行为:

    • 无测试用例循环时程序"正常运行"只是巧合,随机内存地址刚好可写且未破坏关键数据;
    • 加入测试用例循环后,多次执行非法内存写入,直接破坏了程序的栈结构或其他关键内存,导致程序挂起、无输出。
  2. 你怀疑的多变量for循环并非问题根源,但该循环本身也存在逻辑瑕疵:当k==4时执行j--,会导致j在该轮循环结束后被j++抵消,相当于j停在当前位置,下一次循环会重复输出s[j]吗?不,实际逻辑是插入's'后,k继续递增,j保持当前值,下一次循环输出s[j],这部分逻辑是可以实现插入的,但前提是指针s是有效的。

修正方案

步骤1:为字符串分配有效内存

将char *s;改为固定大小的字符数组(或动态分配内存),比如:

char s[256]; // 足够存储常见URL的大小

或者用动态分配:

char *s = malloc(256 * sizeof(char));
if (s == NULL) {
    perror("malloc failed");
    return 1;
}
// 程序结束后记得free(s);

步骤2:修复URL转换的逻辑(可选优化)

原多变量循环的逻辑可以实现插入,但也可以更简洁:

  • 对于http开头的URL,直接输出https,然后输出从第4位开始的原字符串内容,无需循环逐个字符处理:
else {
    printf("Case %d: https%s\n", i+1, s+4);
}

这个写法更高效且避免循环逻辑出错。

完整修正后的代码示例

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

int main()
{
    int T;
    scanf("%d", &T);
    // 处理scanf后的换行符,避免影响后续输入
    getchar();

    for (int i = 0; i < T; i++)
    {
        char s[256];      
        // 用fgets读取更安全,避免缓冲区溢出
        fgets(s, sizeof(s), stdin);
        // 去掉fgets读取的换行符
        s[strcspn(s, "\n")] = '\0';

        if (strncmp(s, "https", 5) == 0) {
            printf("Case %d: %s\n", i+1, s);
        }
        else if (strncmp(s, "http", 4) == 0) {
            printf("Case %d: https%s\n", i+1, s+4);
        }
        else {
            // 处理非http/https开头的URL
            printf("Case %d: %s\n", i+1, s);
        }
    }
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 19:31:08