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

C语言结构体与TXT文件读取函数问题求助

解决租户信息文件读取失效的问题

我帮你排查出了几个导致读取功能无法正常工作的核心问题,咱们一步步修复:

问题分析

  • 错误使用fread读取文本文件:你用fprintf以文本格式写入租户信息,但读取时开头调用了二进制读取的fread,这会读取到乱码并移动文件指针,导致后续fscanf无法定位到正确的内容位置。
  • 依赖运行时变量helper控制读取循环:helper是程序运行中记录添加租户的计数,但如果程序重启,helper会重置为0;而且文件里的实际租户数量可能和helper不一致,这会导致要么读不到数据,要么读取不完整。
  • 未处理租户间的分隔线:写入文件时每个租户后都加了分隔线//////////////////////////////////////////////////////////////////////////,但读取时没有跳过这部分内容,fscanf遇到这行后会因格式不匹配直接停止读取。
  • 读取后未输出内容:你的read函数只是把数据读到tenant数组,但没有打印逻辑,所以就算读取成功也看不到结果。

修复后的代码

1. 修改Functions.c中的read函数

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include "Header.h"

void write(FILE* file, int helper, TENANT* tenant) {
    int i = helper - 1;
    printf("Name of tenant: ");
    scanf("%s", (tenant + i)->fname);
    printf("Last name of tenant: ");
    scanf("%s", (tenant + i)->lname);
    printf("Floor: ");
    scanf("%d", &(tenant + i)->floor);
    printf("Phone: ");
    scanf("%d", &(tenant + i)->phone);
    fprintf(file, "Name: %s\nLast name: %s\nFloor: %d\nPhone: 0%d\n", 
            (tenant + i)->fname, (tenant + i)->lname, (tenant + i)->floor, (tenant + i)->phone);
    fprintf(file, "\n//////////////////////////////////////////////////////////////////////////\n");
}

void read(FILE* file) {
    TENANT temp;
    char separator[200]; // 用来读取分隔线
    // 循环读取直到文件末尾
    while (1) {
        // 读取租户信息
        int result = fscanf(file, "Name: %s\nLast name: %s\nFloor: %d\nPhone: 0%d\n", 
                           temp.fname, temp.lname, &temp.floor, &temp.phone);
        if (result != 4) { // 读取失败(比如到文件末尾)
            break;
        }
        // 打印读取到的租户信息
        printf("=== Tenant Info ===\n");
        printf("First Name: %s\n", temp.fname);
        printf("Last Name: %s\n", temp.lname);
        printf("Floor: %d\n", temp.floor);
        printf("Phone: 0%d\n\n", temp.phone);
        // 跳过分隔线(空行+分隔线本身)
        fgets(separator, sizeof(separator), file);
        fgets(separator, sizeof(separator), file);
    }
}

2. 更新Header.h的函数声明

因为修改了read函数的参数,需要同步更新头文件:

#ifndef HEADER_H
#define HEADER_H
typedef struct tenant {
    char fname[30];
    char lname[30];
    int floor;
    int phone;
}TENANT;
void write(FILE*, int, TENANT*);
void read(FILE*); // 更新参数列表
#endif

3. 调整Source.c中的菜单逻辑

移除重复的fopen调用,增加文件操作失败判断,修复格式符错误:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include "Header.h"
#include <conio.h>

int main() {
    int n = 0, helper = 0;
    char nameFile[100];
    TENANT *tenant = NULL;
    tenant = (TENANT*)calloc(200, sizeof(TENANT));
    FILE *file = NULL;

    printf("Name of building: ");
    scanf("%s", nameFile);
    printf("\n");

    while (n != 4) {
        printf("Press 1 for creating file! \n");
        printf("Press 2 for reading from file! \n");
        printf("Press 3 for adding new tenants! \n");
        printf("Press 4 to close the file! \n\n");
        printf("Number: ");
        scanf("%d", &n);
        printf("\n");

        switch (n) {
            case 1:
                file = fopen(nameFile, "w");
                if (file != NULL) {
                    printf("File created.\n");
                    fclose(file);
                } else {
                    printf("Failed to create file!\n");
                }
                printf("\n");
                break;
            case 2:
                file = fopen(nameFile, "r");
                if (file == NULL) {
                    printf("File is not yet created!\n\n");
                    break;
                } else {
                    read(file);
                    fclose(file);
                }
                printf("\n");
                break;
            case 3:
                helper++;
                printf("Insert details of tenant %d: \n", helper); // 修复格式符缺失问题
                file = fopen(nameFile, "a");
                if (file != NULL) {
                    write(file, helper, tenant);
                    fclose(file);
                } else {
                    printf("Failed to open file for writing!\n");
                }
                printf("\n");
                break;
            case 4:
                printf("Program closed!\n");
                break;
            default:
                printf("Invalid option, please try again!\n\n");
                break;
        }
    }
    free(tenant);
    system("PAUSE");
    return 0;
}

额外优化说明

  • 增加了文件打开/创建的失败判断,避免空指针操作
  • 读取时使用临时TENANT变量,不再依赖传入的数组,逻辑更独立
  • 循环读取直到文件末尾,不管程序重启多少次都能正确读取所有租户信息
  • 修复了原代码中printf格式符缺失的小错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:29:25