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

C语言程序while循环崩溃问题排查求助

问题排查与修复方案

错误原因分析

1. 标准库函数参数非法触发断言

isdigit()、isupper()这类ctype.h中的函数要求参数必须是**unsigned char转换为int**或者EOF。如果直接传入负数的char类型值(比如某些扩展ASCII字符),会触发运行时断言(即你看到的Expression: c >= 0 && c <= 255错误),因为这些函数内部会做参数有效性校验。

2. While循环越界访问

原代码的while循环未限制i的范围,当处理到字符串最后一个单词时,由于结尾没有空格,i会持续递增超过字符串长度,导致数组越界访问,触发未定义行为(程序崩溃)。同时,last_letter的更新逻辑错误,每次循环先处理string[i]再执行i++,导致单词的最后一个字符未被正确记录。

3. 单词首尾字母判断逻辑失效

原代码未跳过开头的空格,会把空格误判为单词起始;遍历单词时也未正确捕获最后一个字符,导致首尾字母比较逻辑完全错误。

修复后的代码

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

void calculation(char string[], int *n_words, int *n_numbers, int *n_uppercase) {
    *n_words = 0;
    *n_numbers = 0;
    *n_uppercase = 0;

    int len = strlen(string);
    int i = 0;

    while (i < len) {
        // 跳过前置空格,定位单词起始
        while (i < len && string[i] == ' ') {
            i++;
        }
        if (i >= len) break; // 已到字符串末尾,终止循环

        char first_letter = string[i];
        // 遍历至单词结束(遇到空格或字符串末尾)
        while (i < len && string[i] != ' ') {
            // 转换为unsigned char避免断言错误
            unsigned char c = (unsigned char)string[i];
            if (isdigit(c)) {
                (*n_numbers)++;
            } else if (isupper(c)) {
                (*n_uppercase)++;
            }
            i++;
        }
        char last_letter = string[i - 1]; // 单词最后一个字符为i-1位置

        // 严格比较首尾字母(若需忽略大小写,可添加tolower/toupper转换)
        if (first_letter == last_letter) {
            (*n_words)++;
        }
    }
}

int main() {
    char tekst[169];
    int n_numbers, n_uppercase, n_words;
    printf("Write a text: \n");
    gets_s(tekst);
    calculation(tekst, &n_words, &n_numbers, &n_uppercase);
    printf("Number of words with the same starting and ending letter: %d\n", n_words);
    printf("Number of upper case characters - number of numbers: %d\n", n_uppercase - n_numbers);

    return 0;
}

关键修复说明

  • ctype函数参数处理:将string[i]转换为unsigned char后再传入isdigit/isupper,彻底避免负数参数触发断言。
  • 循环边界控制:所有循环都校验i < len,从根源杜绝数组越界问题。
  • 单词逻辑修正:先跳过空格定位单词起始,再遍历到单词结束,通过i-1正确获取最后一个字符,确保首尾字母比较逻辑生效。
  • 性能优化:提前计算字符串长度len,避免循环中重复调用strlen(每次调用都会遍历整串,降低效率)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 14:13:01