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

C语言从文件读取数据到动态二维数组遇阻求助

Fixing Your Matrix File Reading Issue

Hey Chiara, let's break down what's going wrong with your read_from_file function and fix it step by step. You've already nailed the row/column calculation and memory allocation—great start! The main issues are in how you're reading the file content and mapping it to your 2D array, plus a critical missing step: resetting the file pointer.

Why Your Current Attempts Fail

First Approach Issues

  • Insufficient Buffer Size: char*buffer = malloc(sizeof(char)); only allocates 1 byte, which is way too small to hold a full row of columns characters plus the null terminator. This causes buffer overflow, leading to undefined behavior like corrupted data or crashes.
  • Wrong Loop Logic: You’re wrapping the row loop inside the fgets loop, which means every time you read a single line, you overwrite all row rows of your matrix with that one line. That’s why your data isn’t populating correctly.
  • Incorrect Null Terminator Handling: Manually grabbing buffer[columns - 1] isn’t the right way to exclude the null terminator—fgets handles that automatically, and you should instead focus on removing unwanted newline characters.

Second Approach Issues

  • Misplaced Nested Loops: Your fgetc loop overwrites the entire matrix with each single character you read. Instead, you need to iterate through each cell of the matrix in order and assign one character per cell.

The Correct Implementation

First, a critical step you’re missing: reset the file pointer to the start of the file. When you calculated the row/column counts earlier, you likely read through the entire file, leaving the pointer at the end (EOF). Without resetting it, subsequent reads will return nothing. Use rewind(fp) or fseek(fp, 0, SEEK_SET) to fix this.

Option 1: Using fgets (Simpler for Line-Based Data)

This method reads one line at a time, maps it directly to a row in your matrix, and cleans up newline characters:

char** read_from_file(int *r, int *col, FILE *fp) {
    // Assume you've already calculated *r (row) and *col (columns) correctly here
    int row = *r;
    int columns = *col;

    // Allocate matrix (your existing code, confirmed working)
    char** p = malloc(row * sizeof(char*));
    if (p == NULL) return NULL;
    for (int i = 0; i < row; i++) {
        p[i] = malloc(columns * sizeof(char));
        if (p[i] == NULL) {
            // Clean up allocated memory on failure
            for (int j = 0; j < i; j++) free(p[j]);
            free(p);
            return NULL;
        }
    }

    // Reset file pointer to start (MISSING IN YOUR CODE!)
    rewind(fp);

    for (int i = 0; i < row; i++) {
        // Read a line into a temporary buffer (columns+1 to fit null terminator)
        char temp_buf[columns + 2]; // Extra space for newline/null
        if (fgets(temp_buf, sizeof(temp_buf), fp) == NULL) {
            // Handle read error: clean up and return
            for (int j = 0; j <= i; j++) free(p[j]);
            free(p);
            return NULL;
        }

        // Remove newline character if present (fgets includes it)
        size_t line_len = strlen(temp_buf);
        if (line_len > 0 && (temp_buf[line_len - 1] == '\n' || temp_buf[line_len - 1] == '\r')) {
            temp_buf[line_len - 1] = '\0';
        }

        // Copy the cleaned line into your matrix row
        strncpy(p[i], temp_buf, columns);
        // Ensure the last character is null-terminated (optional, but safe)
        p[i][columns - 1] = '\0';
    }

    return p;
}

Option 2: Using fgetc (More Control for Character-by-Character Reading)

If you prefer reading one character at a time (useful if your file doesn’t have clear line breaks), use this approach:

char** read_from_file(int *r, int *col, FILE *fp) {
    int row = *r;
    int columns = *col;

    // Allocate matrix (your existing code)
    char** p = malloc(row * sizeof(char*));
    if (p == NULL) return NULL;
    for (int i = 0; i < row; i++) {
        p[i] = malloc(columns * sizeof(char));
        if (p[i] == NULL) {
            for (int j = 0; j < i; j++) free(p[j]);
            free(p);
            return NULL;
        }
    }

    // Reset file pointer to start
    rewind(fp);

    for (int i = 0; i < row; i++) {
        for (int j = 0; j < columns; j++) {
            int c = fgetc(fp);
            // Skip newline/carriage return characters (common in text files)
            while (c == '\n' || c == '\r') {
                c = fgetc(fp);
                if (c == EOF) {
                    // Handle unexpected end of file
                    for (int k = 0; k <= i; k++) free(p[k]);
                    free(p);
                    return NULL;
                }
            }
            // Assign the character to the matrix cell
            p[i][j] = (char)c;
        }
    }

    return p;
}

Key Tips to Avoid File Corruption When Writing

When you write the matrix back to a file, make sure to add newline characters after each row. This ensures the file stays formatted correctly for future reads:

// Example write function
void write_to_matrix(char** p, int row, int columns, FILE *fp) {
    for (int i = 0; i < row; i++) {
        fprintf(fp, "%s\n", p[i]);
    }
}

Final Checks

  • Always validate memory allocation (check if malloc returns NULL) to avoid crashes.
  • Reset the file pointer before reading—this is the most common oversight when calculating rows/columns first.
  • Handle newline characters consistently, as they can break row alignment if ignored.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:02:02