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

使用fgetc()读取文件后字符串出现未定义字符的问题排查

问题分析与修复方案

你遇到的未定义字符问题主要有几个核心原因,咱们一步步拆解:

1. 初始变量未初始化,循环逻辑错误

你的代码里int c , i = 0 ;只初始化了i,c的初始值是随机的,第一次进入while(c != EOF)判断时,c可能刚好等于EOF导致循环直接跳过,或者进入循环后才第一次读取输入,逻辑顺序完全不对。

2. 把EOF存入了数组

当fgetc(stdin)返回EOF时,你依然把它赋值给str[i],而EOF的数值是-1,对应到char类型(如果是有符号char的话)是一个非打印的非法字符,这会直接污染你的字符串内容。

3. 字符串缺少终止符'\0'

C语言中,printf("%s")完全依赖字符串末尾的'\0'来确定结束位置,如果没有这个标记,它会一直读取数组后面的内存,直到遇到随机的空字符,这就是你看到“未定义字符”的核心原因。

4. 未处理数组越界

当输入内容超过1024字符时,i会继续增长,超出数组str[1024]的范围,导致内存溢出,触发更严重的未定义行为。


修正后的代码

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

int main(int argc, char *argv[]){ 
    int c; 
    int i = 0; 
    // 预留一个位置给字符串终止符
    char str[1024]; 
    // 先读取字符再判断是否为EOF,避免初始值问题
    while((c = fgetc(stdin)) != EOF) {
        // 检查数组剩余空间,留最后一个位置存'\0'
        if (i < 1023) {
            str[i] = c;
            i++;
        } else {
            // 可选:处理输入过长的情况,比如提示用户
            fprintf(stderr, "输入内容过长,已截断\n");
            break;
        }
    }
    // 手动添加字符串终止符,这是解决乱码的关键
    str[i] = '\0'; 
    printf("%s\n", str); 
    return 0; 
}

关键修改说明:

  • 调整循环顺序:先执行c = fgetc(stdin)再判断是否为EOF,既避免了初始c未定义的问题,也不会把EOF存入数组。
  • 添加数组越界检查:确保i最大到1023,留最后一个位置给'\0',彻底防止内存溢出。
  • 手动添加终止符:循环结束后给str[i]赋值'\0',让printf能正确识别字符串的结束位置,不会读取额外的内存内容。

这样修改后,你再执行test < file.json就不会出现未定义字符了。

内容的提问来源于stack exchange,提问作者Haskell-newb

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:08:55