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

如何从文件读取交替行并存入结构体字符串?C程序实现文件读取至动态结构体数组

Alright, let's break this down step by step to solve your problem with reading that log file into a dynamically allocated struct array, plus handling alternate lines.

Solution for Reading Log Files into C Struct Arrays

1. First, Define Your Log Entry Struct

We'll start with a struct to hold each log entry's date and content. We'll set fixed sizes for simplicity (adjust MAX_LINE_LENGTH if your logs are longer):

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

#define MAX_LINE_LENGTH 256

typedef struct {
    char date[11];  // Fits DD/MM/YYYY plus null terminator
    char content[MAX_LINE_LENGTH];
} LogEntry;

2. Read the File & Allocate Dynamic Memory

Here's the core code to open the file, read the entry count, allocate memory for the struct array, and populate it:

int main() {
    FILE *file = fopen("logs.txt", "r");
    if (!file) {
        perror("Failed to open log file");
        return 1;
    }

    int entryCount;
    // Read the first line's integer (number of log entries)
    if (fscanf(file, "%d", &entryCount) != 1) {
        fprintf(stderr, "Error reading entry count from file\n");
        fclose(file);
        return 1;
    }
    // Critical: fscanf leaves a newline in the buffer — skip it so fgets works correctly
    getchar();

    // Dynamically allocate the struct array
    LogEntry *logArray = malloc(entryCount * sizeof(LogEntry));
    if (!logArray) {
        perror("Failed to allocate memory for logs");
        fclose(file);
        return 1;
    }

    // Populate each struct in the array
    for (int i = 0; i < entryCount; i++) {
        char line[MAX_LINE_LENGTH];
        if (fgets(line, sizeof(line), file) == NULL) {
            fprintf(stderr, "Error reading log entry #%d\n", i+1);
            free(logArray); // Clean up already allocated memory
            fclose(file);
            return 1;
        }

        // Split date (first 10 chars) and content (remaining chars)
        strncpy(logArray[i].date, line, 10);
        logArray[i].date[10] = '\0'; // Ensure null-terminated string

        // Copy content, skip the date and following space
        strncpy(logArray[i].content, line + 11, sizeof(logArray[i].content) - 1);
        logArray[i].content[sizeof(logArray[i].content) - 1] = '\0';
        // Remove trailing newline from content
        size_t contentLen = strlen(logArray[i].content);
        if (contentLen > 0 && logArray[i].content[contentLen-1] == '\n') {
            logArray[i].content[contentLen-1] = '\0';
        }
    }

    // Example: Print all logs to verify
    printf("Successfully read %d log entries:\n", entryCount);
    for (int i = 0; i < entryCount; i++) {
        printf("[%s] %s\n", logArray[i].date, logArray[i].content);
    }

    // Clean up resources
    free(logArray);
    fclose(file);
    return 0;
}

3. Reading Alternate Lines into Structs

If you want to only read every other line (e.g., odd-numbered entries, even-numbered entries), add a simple condition during the read loop. Here's how to modify the code to capture alternate lines:

Example: Read Only Odd-Numbered Log Entries

// After reading the full log array (or reset the file pointer to re-read)
rewind(file);
getchar(); // Skip the initial newline again

int alternateCount = (entryCount + 1) / 2; // Calculate how many alternate entries exist
LogEntry *alternateLogs = malloc(alternateCount * sizeof(LogEntry));
if (!alternateLogs) {
    perror("Failed to allocate memory for alternate logs");
    free(logArray);
    fclose(file);
    return 1;
}

int altIdx = 0;
for (int i = 0; i < entryCount; i++) {
    char line[MAX_LINE_LENGTH];
    if (fgets(line, sizeof(line), file) == NULL) {
        fprintf(stderr, "Error reading line #%d\n", i+1);
        free(alternateLogs);
        free(logArray);
        fclose(file);
        return 1;
    }

    // Only process odd entries (i starts at 0, so i%2==0 is 1st, 3rd, etc.)
    if (i % 2 == 0) {
        // Same date/content split as before
        strncpy(alternateLogs[altIdx].date, line, 10);
        alternateLogs[altIdx].date[10] = '\0';

        strncpy(alternateLogs[altIdx].content, line + 11, sizeof(alternateLogs[altIdx].content) - 1);
        alternateLogs[altIdx].content[sizeof(alternateLogs[altIdx].content) - 1] = '\0';

        size_t len = strlen(alternateLogs[altIdx].content);
        if (len > 0 && alternateLogs[altIdx].content[len-1] == '\n') {
            alternateLogs[altIdx].content[len-1] = '\0';
        }

        altIdx++;
    }
}

// Print alternate entries
printf("\nAlternate (odd-numbered) log entries:\n");
for (int i = 0; i < alternateCount; i++) {
    printf("[%s] %s\n", alternateLogs[i].date, alternateLogs[i].content);
}

free(alternateLogs);

Quick Tips to Avoid Headaches

  • Always check for errors when opening files, allocating memory, or reading lines — this prevents crashes and makes debugging way easier.
  • If your date format isn't exactly 10 characters, use sscanf instead of strncpy for more robust parsing (e.g., sscanf(line, "%10s %[^\n]", logArray[i].date, logArray[i].content);).
  • To read even-numbered entries instead, change the condition to i % 2 == 1.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:17:47