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

C语言首字母缩写生成器异常:fgets未执行且输出乱码求助

问题分析与解决方案

核心问题

  • 输入缓冲区残留换行:scanf("%d", &R)读取完整数后,用户输入的换行符会留在输入缓冲区,第一个fgets会直接读取这个空换行,导致stringA[0]为空。
  • 字符串未终止:stringB只存储了大写字母,但没有添加C语言字符串必需的终止符'\0',输出时会读取到内存中随机的垃圾数据,表现为乱码。
  • fgets读取换行符:fgets会将用户输入的换行符也存入字符串,导致输出时格式混乱。

修改后的完整代码

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

int main() {
    int R;

    printf("Enter the number of acronyms to add to the database: ");
    scanf("%d", &R);
    // 清除scanf残留的换行符
    getchar();

    char stringA[R][50];
    char stringB[R][7];

    for(int i=0; i<R; i++){
        int b = 0;
        // 初始化stringB,避免残留垃圾数据
        memset(stringB[i], 0, 7);

        printf("\nEnter the string to convert into an acronym: ");
        fgets(stringA[i], 50, stdin);
        
        // 去掉fgets读取的换行符
        size_t len = strlen(stringA[i]);
        if(len > 0 && stringA[i][len-1] == '\n'){
            stringA[i][len-1] = '\0';
        }

        for(int j=0; stringA[i][j] != '\0'; j++){
            if(stringA[i][j] >= 'A' && stringA[i][j] <= 'Z'){
                // 防止stringB越界
                if(b < 6){
                    stringB[i][b] = stringA[i][j];
                    b++;
                }
            }
        }
        // 手动添加终止符(也可通过memset提前初始化)
        stringB[i][b] = '\0';

        printf("Acronym of '%s' is '%s'\n", stringA[i], stringB[i]);
    }
    return 0;
}

关键修改点

  1. 清除输入缓冲区:在scanf后调用getchar(),吃掉残留的换行符,确保后续fgets能正确读取用户输入。
  2. 字符串终止处理:
    • 用memset初始化stringB为0,避免内存残留数据
    • 循环结束后手动给stringB[i]添加'\0',保证是合法C字符串
  3. 处理fgets的换行符:判断字符串末尾是否为换行符,替换为'\0',避免输出时的格式问题
  4. 优化循环条件:将j<50改为stringA[i][j] != '\0',只遍历到字符串实际长度,无需遍历整个数组
  5. 越界保护:添加if(b <6)判断,防止stringB超出数组长度(因为stringB定义为7位,最多存6个字符+1个终止符)
  6. 调整输出格式:用'%s'替代固定宽度格式,避免多余空格,同时用单引号包裹内容更清晰

内容的提问来源于stack exchange,提问作者Kai Young

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 14:41:26