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

C语言写入txt文件时吞掉输入字符串首字符、格式异常问题排查

问题描述

该函数用于向txt文件写入3项用户输入内容,分别为ID、分类(category)、描述(description),其中ID应为整数类型,其余两项为字符串类型。

问题复现代码

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

void addtask();
char menu();

int main() {
    char selection ;
   do {
    selection = menu() ;
    switch(selection) {
        case '1': addtask(); break;
        case '2': break;
        default: printf("\n\n\nInvalid key entered");
    }
   }while(selection != '2');
   return 0;
}

char menu() {
    char option;
    printf("\nWelcome to the task management system. Please enter a key to continue...\n");
    printf("\n1) Add new task");
    printf("\n2) Save and quit\n");
    scanf("%c[^\n]", &option);
    return option;
}

void addtask() {
    int id;char category[21];char description[101];
    printf("\nCreating new task...\n\n");
    FILE * f = fopen("tasklist.txt", "r+");
    if(f == NULL){
        printf("File does not exist. Creating new file...");
        f = fopen("tasklist.txt", "w");
    }
    else {
            fseek(f, 0, SEEK_END);  //move to end of cursor
            printf("\nENTER id:");
            scanf("%d", &id);
            printf("\nEnter category (max 20 characters): ");
            getchar();
            fgets(category, 21, stdin);
            printf("\nEnter description (max 100 characters): ");
            getchar();
            fgets(description, 101, stdin);
            printf("writing: %d \t %s \t %s \t", id, category, description);
            fprintf(f,"%d \t %s \t %s \t", id, category, description);
    }
    fclose(f);
}

异常表现

运行程序并输入2组ID、分类、描述内容后,txt文件中实际输出内容如下:

1    Cat1
     esc1
    2    Cat2
     esc2

预期正确输出应为:

1    Cat1   Desc1
2    Cat2   Desc2
问题原因分析

代码存在4个核心问题,直接导致输出异常:

  • 首次创建文件时写入逻辑完全缺失:当tasklist.txt不存在时,代码仅以写模式创建空文件,没有执行任何输入读取、写入操作就直接关闭文件,首次运行选择添加任务时根本不会写入任何内容。
  • 输入缓冲区处理逻辑错误:
    • scanf("%d", &id)读取整数时,会把用户输入ID后按下的回车符\n留在输入缓冲区中。读取描述前额外多调用了一次getchar(),会直接吞掉用户输入的描述内容的第一个字符——这就是输入Desc1最终文件里显示esc1的直接原因,首字母D被多余的getchar()吃掉了。
    • fgets()读取字符串时,会把用户输入完内容后按下的回车符一并存入字符串末尾,写入文件时就会自带换行,导致Cat1写完直接换行,和后面的描述内容错位。
  • menu()函数的scanf格式符写法错误:%c[^\n]是无效写法,%c仅匹配单个字符,后面跟[^\n]不符合格式规则,会导致菜单选项读取异常,残留的换行符还会干扰后续输入流程。
  • 文件打开逻辑冗余易错:原代码先用r+模式打开文件,不存在再切w模式,把所有写入逻辑全放在else分支里,是导致首次创建文件无法写入的根本原因。
修复方案

对应问题逐一修改即可:

  • 直接用追加模式a打开文件,该模式下文件不存在会自动创建,存在则自动将光标定位到文件末尾,不需要手动调用fseek,也不用分支判断文件是否存在。
  • 修正menu函数的scanf格式,用scanf(" %c", &option),格式串前的空格会自动跳过所有残留的空白字符(换行、空格等),每次读取完选项后清空输入缓冲区。
  • 移除读取描述前多余的getchar(),每次用scanf读取整数后统一清空缓冲区到换行,避免残留字符干扰后续输入。
  • 读取完category和description后,手动将字符串末尾fgets读入的换行符替换为字符串结束符\0,避免写入文件时出现多余换行。

修复后的核心代码参考:

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

void addtask();
char menu();

int main() {
    char selection ;
   do {
    selection = menu() ;
    switch(selection) {
        case '1': addtask(); break;
        case '2': break;
        default: printf("\n\n\nInvalid key entered");
    }
   }while(selection != '2');
   return 0;
}

char menu() {
    char option;
    printf("\nWelcome to the task management system. Please enter a key to continue...\n");
    printf("\n1) Add new task");
    printf("\n2) Save and quit\n");
    scanf(" %c", &option);
    // 清空缓冲区残留字符
    while(getchar() != '\n');
    return option;
}

void addtask() {
    int id;char category[21];char description[101];
    printf("\nCreating new task...\n\n");
    // 直接用追加模式打开,自动处理不存在/光标定位逻辑
    FILE * f = fopen("tasklist.txt", "a");
    if(f == NULL){
        printf("Failed to open file!\n");
        return;
    }
    printf("\nENTER id:");
    scanf("%d", &id);
    // 清空scanf残留的换行
    while(getchar() != '\n');
    printf("\nEnter category (max 20 characters): ");
    fgets(category, 21, stdin);
    // 截断fgets读入的换行符
    category[strcspn(category, "\n")] = '\0';
    printf("\nEnter description (max 100 characters): ");
    fgets(description, 101, stdin);
    // 截断fgets读入的换行符
    description[strcspn(description, "\n")] = '\0';
    printf("writing: %d \t %s \t %s \n", id, category, description);
    fprintf(f,"%d \t %s \t %s \n", id, category, description);
    fclose(f);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 14:21:08