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

C语言putw写入int到文件乱码、getw读取返回-1问题求解

贪吃蛇高分存储功能写入乱码、读取值变-1问题修复

问题相关代码

fp = fopen("rank.txt", "w");
if(fp == NULL){
   clear();
   refresh();
   mvprintw(y/2,x/2-5,"File Error");
   sleep(3);
   break;
     }
     else{
       ch1 = getw(fp);
         if(score > ch1){
         mvprintw(y/2-2,x/2-(strlen(title)/2),"%s", title);
         mvprintw(y/2,x/2-(strlen(rank)/2), "%s", rank);
         mvprintw(y/2+2, x/2, "%d", score);
         refresh();
         sleep(5);
         putw(score,fp);
         fclose(fp);
         break;
       }

       else{
         mvprintw(y/2-2,x/2-(strlen(title)/2),"%s", title);
         mvprintw(y/2,x/2-3,"SCORE:");
         mvprintw(y/2+2, x/2, "%d", score);
         refresh();
         fclose(fp);
         break;
        }
      }
    }

错误定位

代码一共有3个核心问题,直接对应你遇到的两个故障现象:

  • 文件打开模式完全错误:你用"w"模式打开文件,该模式是只写模式,打开瞬间会直接清空文件原有所有内容,且不支持读操作。你在打开后立刻调用getw()读历史高分,此时文件已经被清空,且在只写流上执行读操作属于未定义行为,根本读不到之前存储的有效分数。
  • 读写函数使用错误:getw()/putw()是二进制读写函数,直接把int类型的二进制字节流写入文件,不是写入人类可读的数字ASCII字符,所以你用文本编辑器打开rank.txt看到的自然是乱码。同时这两个函数在读失败、读到文件尾时会返回EOF(值为-1),你没有做任何读成功校验就直接使用返回值,这就是分数显示几秒后变成-1的直接原因。
  • 逻辑顺序错误:文件打开后没有先判断读操作是否成功,直接拿无效的读结果和当前分数做比较,后续写入的位置也因为之前的非法读操作出现偏移,写入的内容根本不在文件正确位置。

修复方案

推荐用明文文本格式存储分数,方便调试排查,也不会出现乱码问题,修复逻辑如下:

  1. 先以只读模式"r"打开rank.txt,读取历史最高分,读取完成后关闭文件;如果文件打开失败(首次运行游戏还没生成分数文件),就把历史最高分默认设为0。
  2. 再以只写模式"w"打开文件,判断当前分数是否超过历史最高分:如果超过就把新的最高分写入文件,否则保留旧的最高分写入。
  3. 读写整数改用格式化IO函数fscanf()/fprintf(),写入的内容是明文数字,直接打开txt文件就能看到正常数值。

修复后的参考代码:

int ch1 = 0;
FILE *fp = fopen("rank.txt", "r");
// 先读取历史最高分
if (fp != NULL) {
    fscanf(fp, "%d", &ch1);
    fclose(fp);
}
// 重新打开文件写入最新最高分
fp = fopen("rank.txt", "w");
if(fp == NULL){
    clear();
    refresh();
    mvprintw(y/2,x/2-5,"File Error");
    sleep(3);
    break;
}
if(score > ch1){
    mvprintw(y/2-2,x/2-(strlen(title)/2),"%s", title);
    mvprintw(y/2,x/2-(strlen(rank)/2), "%s", rank);
    mvprintw(y/2+2, x/2, "%d", score);
    refresh();
    sleep(5);
    fprintf(fp, "%d", score);
}else{
    mvprintw(y/2-2,x/2-(strlen(title)/2),"%s", title);
    mvprintw(y/2,x/2-3,"SCORE:");
    mvprintw(y/2+2, x/2, "%d", score);
    refresh();
    fprintf(fp, "%d", ch1);
}
fclose(fp);
break;

如果你确实需要用二进制模式存储分数,要把文件打开模式改为带b的二进制模式(如"rb"、"wb"),同时替换getw/putw为移植性更好的fread/fwrite,注意跨平台运行时要处理字节序和int长度差异问题。

内容的提问来源于stack exchange,提问作者Suki Sebastian

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 18:06:25