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

按下退格键后C语言程序写入文件出现不可读字符的问题求助

退格键输入后文件写入乱码的问题解决

问题现象

正常输入时程序运行无异常,但按下退格键修正输入错误后,写入文件的内容变为人类无法读取的乱码。原代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<conio.h> 

void main(void)
{
    FILE *poointer;
    poointer= fopen("TestingXX.txt","w"); 
    char ch;
    
     while ( (ch=getche()) != '\r') 
        {
            putc(ch,poointer);                                
        }

    fclose(poointer);

}

问题原因

  • getche()会直接返回退格键对应的ASCII控制字符(0x08),而非处理退格的视觉删除逻辑。这个控制字符被写入文件后,普通文本编辑器无法正常解析,因此显示为乱码。
  • 原代码仅将输入的每个字符直接写入文件,未处理退格操作对应的“删除已写入字符”逻辑:屏幕上字符看似被删除,但文件中已写入的前一个字符并未移除,还额外添加了退格控制字符。

修复方案

方案1:直接操作文件指针处理退格

捕获退格键时,回退文件指针并覆盖前一个字符,同时在屏幕上实现正确的退格视觉效果:

#include<stdio.h>
#include<stdlib.h>
#include<conio.h> 

int main(void) // 遵循C标准,main函数返回int类型
{
    FILE *poointer;
    poointer = fopen("TestingXX.txt", "w"); 
    if (poointer == NULL) { // 增加文件打开失败的错误处理
        perror("Failed to open file");
        return 1;
    }
    
    char ch;
    long current_pos;
    
    while ( (ch = getche()) != '\r') 
    {
        if (ch == '\b') { // 识别退格键(ASCII 0x08)
            current_pos = ftell(poointer);
            if (current_pos > 0) {
                // 将文件指针回退一位,覆盖前一个字符
                fseek(poointer, current_pos - 1, SEEK_SET);
                fputc('\0', poointer);
                fseek(poointer, current_pos - 1, SEEK_SET);
                
                // 在屏幕上实现退格视觉效果:退格+空格+退格
                printf("\b \b");
            }
        } else {
            putc(ch, poointer);
        }
    }

    fclose(poointer);
    return 0;
}

方案2:内存缓冲区暂存输入(更推荐)

先将输入内容存入内存缓冲区,处理完所有退格操作后再一次性写入文件,逻辑更简洁高效:

#include<stdio.h>
#include<stdlib.h>
#include<conio.h> 

#define BUFFER_SIZE 1024

int main(void)
{
    FILE *poointer;
    poointer = fopen("TestingXX.txt", "w"); 
    if (poointer == NULL) {
        perror("Failed to open file");
        return 1;
    }
    
    char buffer[BUFFER_SIZE];
    int buffer_len = 0;
    char ch;
    
    while ( (ch = getche()) != '\r') 
    {
        if (ch == '\b') {
            if (buffer_len > 0) {
                buffer_len--; // 缓冲区长度减1,等效删除最后一个字符
                printf("\b \b"); // 同步屏幕显示
            }
        } else if (buffer_len < BUFFER_SIZE - 1) {
            buffer[buffer_len++] = ch; // 正常字符加入缓冲区
        }
    }
    buffer[buffer_len] = '\0'; // 添加字符串终止符
    
    fputs(buffer, poointer); // 一次性写入文件
    fclose(poointer);
    return 0;
}

内容的提问来源于stack exchange,提问作者0x0040Coder

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 10:35:24