You need to enable JavaScript to run this app. 使用fscanf写入char**数组时,写入过程打印正常,完成后遍历打印输出异常
优惠活动
大模型
产品
解决方案
定价
更多

使用fscanf写入char**数组时,写入过程打印正常,完成后遍历打印输出异常

输出异常的核心原因

你遇到的输出差异根本不是两种打印方式的区别导致的,是代码本身存在严重的内存管理错误,只是写入阶段的临时打印刚好没有触发内存覆盖的问题,才出现了“单步打印正常、整体遍历混乱”的假象。

代码中的具体错误点

  • 对char**数组的内存分配逻辑理解偏差。你通过malloc(1000*sizeof(char*))申请的空间,仅仅是1000个可以存储char*指针的容器,这些指针本身没有被初始化,全部是指向随机内存位置的野指针,没有指向任何可合法写入字符的缓冲区。
  • fscanf的传参完全错误。stop_words[i]本身就是char*类型,作为字符串读取的目标地址直接传入即可,但你写的&stop_words[i]是char**类型,和函数要求的入参类型完全不匹配。这行代码实际执行时,会把读取到的字符串内容,直接硬写入野指针指向的随机内存地址,完全不受控。
  • 循环判断存在经典bug。用while(!feof(fp))做循环条件,会导致读到文件末尾时多执行一次循环,进一步加剧野指针写内存的问题。

两种打印场景的表现差异来源

  • 写入过程中临时打印:每次fscanf刚把一串字符写入某块随机内存,紧接着就从同一地址读取打印,此时这块内存还没有被后续的写入操作覆盖,因此能读到刚写入的完整字符串,看起来输出正常。
  • 全部写入完成后遍历打印:循环后续的每一次fscanf操作,都会往新的野指针对应的随机内存写字符串。由于野指针的指向是随机的,且相邻的野指针指向的内存位置通常很近,新写入的字符串会直接覆盖之前已经存储的旧字符串的尾部。你看到的immediatimportanimportanindex这类混乱输出,就是后面写入的单词内容截断、覆盖了前面存储的单词的后半段,最终遍历读到的就是被反复拼接、截断的无效字符串。

正确实现的注意事项

  • 给每个数组元素单独分配合法的字符缓冲区。每读取一个单词前,先给对应的stop_words[i]申请足够长度的可写内存,比如按最长单词255字节计算,执行stop_words[i] = malloc(256 * sizeof(char))。
  • 修正fscanf的调用方式。去掉多余的取地址符,同时限制读取长度避免溢出,写成fscanf(fp, "%255s", stop_words[i])。
  • 修正循环判断逻辑。不要用feof做循环条件,直接判断fscanf的返回值是否匹配预期,写成while(fscanf(fp, "%255s", stop_words[i]) == 1) { i++; },确保循环在真正读到有效单词时才执行自增。
  • 遍历打印时只遍历到实际有效单词的索引i值,不要遍历到固定的1000次避免访问未初始化的指针。

内容的提问来源于stack exchange,提问作者Hakan Alp

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.25 05:15:01