如何从文件读取交替行并存入结构体字符串?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
sscanfinstead ofstrncpyfor 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
相关产品推荐
相关产品推荐

