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š
相关产品推荐
相关产品推荐

