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

C语言函数参数返回值问题:字符串大写与元音计数始终为0

问题分析与代码修复:大写字母和元音计数始终为0的问题

嘿,我帮你定位到代码里的几个关键问题啦,正是它们导致你的大写字母和元音计数一直返回0,咱们一步步拆解并修复:

1. 计数变量未初始化

在main函数里,你声明了int upper, chars;但没有给它们初始值。C语言的局部变量默认不会自动初始化为0,它们的初始值是内存里的随机垃圾值。当你在StringChange函数里对*upper和*chars做累加操作时,本质是在垃圾值上修改,最终结果自然不对(你看到的0只是巧合的未定义行为)。

修复方式:在main里显式初始化这两个变量:

int upper = 0, chars = 0;

2. 循环索引越界 + 统计范围遗漏

你的循环是for (i = 1; i <= length; i++),这里有两个核心问题:

  • 当i == length时,text[i]访问的是字符串的结束符'\0',这属于数组越界访问,会触发未定义行为;
  • 循环只处理了text[1]到text[length-1]的内容,而text[0]你单独做了大写转换,但完全没把它纳入大写字母的统计范围。

修复方式:调整循环范围为从0到length-1,同时给text[i-1]的判断加边界保护:

for (i = 0; i < length; i++) {
    // 加i>0避免访问text[-1]越界
    if (i > 0 && text[i-1] == '*' && (text[i] >= 'a' && text[i] <= 'z')) {
        text[i] -= 32;
    }
    // 其余逻辑调整索引后正常执行
}

另外,别忘了在处理text[0]的大写转换后,手动统计这个大写字母。

3. 元音统计未覆盖大写情况

你的代码只检查了小写的元音字母(a/e/i/o/u/y),但大写的元音(A/E/I/O/U/Y)完全没被统计进去,这会导致计数偏少,甚至如果字符串全是大写元音的话计数为0。

修复方式:要么直接把大写元音加入判断条件,要么用标准库函数统一转小写后判断(更简洁):

// 方式1:直接加大写判断
if (text[i] == 'a' || text[i] == 'e' || text[i] == 'i' || text[i] == 'o' || text[i] == 'u' || text[i] == 'y' ||
    text[i] == 'A' || text[i] == 'E' || text[i] == 'I' || text[i] == 'O' || text[i] == 'U' || text[i] == 'Y') {
    *chars += 1;
}

// 方式2:转小写后判断(需要包含<ctype.h>头文件)
char c = tolower(text[i]);
if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' || c == 'y') {
    *chars += 1;
}

完整修复后的代码

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <ctype.h> // 用于tolower/toupper等字符处理函数

char *StringChange(char *text, int *upper, int *chars);

int main(void) {
    char text[40];
    int upper = 0, chars = 0; // 显式初始化计数变量
    puts("Type a string");
    gets(text); // 注意:gets函数存在安全风险,实际开发建议用fgets替代
    StringChange(text, &upper, &chars);
    puts("Change words to start with upper case and change white space to *");
    puts(text);
    printf("Quantity of upper case in string: %d\n", upper);
    printf("Quantity of vowels: %d", chars);
    getch();
    return 0;
}

char *StringChange(char *text, int *upper, int *chars) {
    int i, length;
    length = strlen(text);
    for (i = 0; i < length; i++) {
        // 处理单词首字母大写(仅当前一个字符是*时)
        if (i > 0 && text[i-1] == '*' && islower(text[i])) {
            text[i] = toupper(text[i]);
        }
        // 空格转*
        if (text[i] == ' ') {
            text[i] = '*';
        }
        // 统计大写字母
        if (isupper(text[i])) {
            (*upper)++;
        }
        // 统计元音(大小写都算)
        char c = tolower(text[i]);
        if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' || c == 'y') {
            (*chars)++;
        }
    }
    // 处理第一个字符的大写转换,并统计
    if (islower(text[0])) {
        text[0] = toupper(text[0]);
        (*upper)++;
    }
    return text;
}

额外说明:我把手动的ASCII加减替换成了isupper、islower这些标准库函数,让代码更可读且跨平台。另外,gets函数存在缓冲区溢出风险,实际开发中建议用fgets(text, sizeof(text), stdin)替代,记得处理输入末尾的换行符。

内容的提问来源于stack exchange,提问作者Ondřej Javorský

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:04:51