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

字符串字母统计程序用户输入读取异常问题求助

字符串字母统计程序的用户输入问题修复

你的代码核心问题是字符指针未分配有效内存,导致fgets写入非法内存区域,引发未定义行为,这就是输入后统计结果异常的根本原因。以下是具体分析和修复方案:

问题点解析

  • char *s;仅声明了一个字符指针,但未指向任何已分配的内存空间。fgets(&s[0],98,stdin)试图向这块未定义的内存写入数据,会导致程序行为不可预测(比如统计结果错误、程序崩溃等)。
  • 之前用scanf时,如果输入包含空格,scanf("%s", s)会在空格处停止读取,只能获取第一个单词,这也会造成“仅统计到一次字母”的错觉(如果输入是单个单词但内存非法,同样会有问题)。

修复后的代码

使用固定大小的字符数组存储输入(最简单可靠的方式,适合初学者):

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

int main() {
    // 定义足够大的字符数组,存储用户输入(最多99个字符+终止符)
    char s[100];
    
    // 读取整行输入,处理读取失败的情况
    if (fgets(s, sizeof(s), stdin) == NULL) {
        printf("输入读取失败\n");
        return 1;
    }

    // 移除fgets自动读取的换行符(如果存在)
    size_t len = strlen(s);
    if (len > 0 && s[len - 1] == '\n') {
        s[len - 1] = '\0';
        len--;
    }

    int letter_counts[26] = {0};
    char c;
    for (size_t i = 0; i < len; i++) {
        c = toupper(s[i]);
        if (c >= 'A' && c <= 'Z') {
            letter_counts[c - 'A']++;
        }
    }

    // 输出统计结果
    for (int i = 0; i < 26; i++) {
        if (letter_counts[i] > 0) {
            printf("%c%d ", 'A' + i, letter_counts[i]);
        }
    }
    return 0;
}

关键修正说明

  1. 替换指针为数组:用char s[100];直接在栈上分配固定内存,避免指针未初始化的问题。
  2. 处理fgets的换行符:fgets会把用户输入的换行符\n也读取进来,手动移除可以避免不必要的字符干扰(虽然toupper后换行符不会被统计,但去掉更严谨)。
  3. 增加输入错误判断:如果fgets返回NULL,说明输入读取失败(比如EOF),提前终止程序。

可选:动态内存分配方案

如果需要灵活的内存大小,可以使用动态分配(记得用完释放内存):

#define _CRT_SECURE_NO_WARNINGS
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
    // 动态分配100字节内存
    char *s = malloc(100 * sizeof(char));
    if (s == NULL) {
        printf("内存分配失败\n");
        return 1;
    }

    if (fgets(s, 100, stdin) == NULL) {
        printf("输入读取失败\n");
        free(s);
        return 1;
    }

    size_t len = strlen(s);
    if (len > 0 && s[len - 1] == '\n') {
        s[len - 1] = '\0';
        len--;
    }

    int letter_counts[26] = {0};
    char c;
    for (size_t i = 0; i < len; i++) {
        c = toupper(s[i]);
        if (c >= 'A' && c <= 'Z') {
            letter_counts[c - 'A']++;
        }
    }

    for (int i = 0; i < 26; i++) {
        if (letter_counts[i] > 0) {
            printf("%c%d ", 'A' + i, letter_counts[i]);
        }
    }

    // 释放动态分配的内存
    free(s);
    return 0;
}

内容的提问来源于stack exchange,提问作者Codin' Cole

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 01:20:38