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

C语言二进制字符串01/10对统计代码异常求助:n≥6时结果为0

问题诊断与修复:二进制字符串相邻01/10对统计异常

核心错误分析

代码里的scanf("%s",&s[n]);是导致异常的根本原因:

  • 你声明了长度为n的字符数组s,合法索引范围是0到n-1,&s[n]指向的是数组越界后的内存地址。
  • 当你把输入的字符串写到这个越界位置时,会直接破坏栈上的其他变量(比如j、count或者数组s本身的起始数据)。
  • 为什么n<6时看似正常?这是栈内存布局的巧合:小数组场景下,越界写入的位置还没覆盖到关键变量;当n≥6时,越界写入直接把s[0]改成了'\0',导致while(s[j]!='\0')循环一开始就终止,count自然为0。

其他潜在问题

  1. 循环越界访问:原代码的while循环中,当j走到字符串最后一个字符时,s[j+1]会访问到字符串结束符'\0'甚至更后面的未知内存,逻辑上完全没必要——我们只需要统计相邻的二进制字符对,不需要判断最后一个字符和'\0'的组合。
  2. 输入长度风险:如果输入的字符串长度等于n,数组会没有空间存储字符串结束符'\0',导致while循环读取到非法内存。

修正后的代码

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

int main() {
    int i, t, j, count;
    int n;
    scanf("%d", &t);
    getchar(); // 吃掉输入t后的换行符,避免干扰后续字符串读取

    for(i=0; i<t; i++) {
        scanf("%d", &n);
        getchar(); // 吃掉输入n后的换行符
        char s[n+1]; // 多开一个空间存字符串结束符
        fgets(s, sizeof(s), stdin);
        
        // 去掉fgets读取到的换行符(如果存在)
        s[strcspn(s, "\n")] = '\0';

        count = 0;
        // 只遍历到倒数第二个字符,避免访问s[n]
        for(j=0; j < n-1; j++) {
            if((s[j]=='1' && s[j+1]=='0') || (s[j]=='0' && s[j+1]=='1')) {
                count++;
            }
        }
        printf("%d\n", count);
    }
    return 0;
}

关键修正点

  • 把错误的scanf("%s",&s[n]);改为fgets(s, sizeof(s), stdin),确保字符串写入数组的合法内存范围,fgets还能限制输入长度,避免溢出。
  • 改用for循环遍历到n-2,彻底避免越界访问数组。
  • 处理输入时的换行符,防止fgets读取到空行影响结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 02:25:53