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

C语言从stdin txt文件读取不同行列、数据类型矩阵的问题求助

问题分析与解决方案

一、现有代码的错误点

  • 变量i未初始化:定义int i后没有赋值为0,初始值为栈内存的随机垃圾值,第一次访问input[i]就属于越界访问,触发未定义行为。
  • 重复调用scanf:while判断条件中已经调用一次scanf读取了一个值,循环体内又调用一次scanf,每次循环会直接丢弃第一次读取的值,仅保留第二次的读取结果。
  • 未处理分隔符:输入的数字之间用逗号分隔,%lf格式符仅能识别数字和空白字符,遇到逗号就会匹配失败,导致后续所有读取操作失效。

二、基础读取逻辑修复

你可以先运行以下测试代码验证读取逻辑,已经适配逗号分隔的输入格式:

#include <stdio.h>
int main() {
    double input[100];
    int i = 0;
    // 格式符前面的空格跳过所有空白,%*c跳过读取到数字后的逗号/换行等分隔符
    while (i < 100 && scanf(" %lf%*c", &input[i]) == 1) {
        printf("%.2lf \n", input[i]);
        i++;
    }
    return 0;
}

三、未知行列矩阵的完整实现方案

核心思路

  1. 逐行读取输入内容,拆分每行的数字元素,第一行拆分出的元素数量即为矩阵列数
  2. 使用动态内存分配存储矩阵元素,通过realloc动态扩展数组容量,适配任意大小的矩阵
  3. 每成功读取一行,行数累加,最终返回动态分配的矩阵数组、行数、列数

完整函数实现

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

// 返回值:0 读取成功,-1 读取失败
// out_mat: 输出参数,返回动态分配的一维矩阵数组(行优先存储)
// out_rows: 输出参数,返回矩阵行数
// out_cols: 输出参数,返回矩阵列数
int readMatrix(double **out_mat, int *out_rows, int *out_cols) {
    char *line = NULL;
    size_t line_buf_size = 0;
    ssize_t line_len;
    double *mat = NULL;
    int rows = 0, cols = 0, total_elems = 0, cap = 0;
    const int BLOCK_SIZE = 64; // 每次扩容的元素数量

    while ((line_len = getline(&line, &line_buf_size, stdin)) != -1) {
        char *ptr = line;
        int line_elems = 0;
        double val;
        int offset;

        // 拆分当前行的所有数字
        while (sscanf(ptr, " %lf%n", &val, &offset) == 1) {
            // 数组容量不足则扩容
            if (total_elems >= cap) {
                cap += BLOCK_SIZE;
                double *tmp = realloc(mat, cap * sizeof(double));
                if (!tmp) {
                    free(mat);
                    free(line);
                    return -1;
                }
                mat = tmp;
            }
            mat[total_elems++] = val;
            line_elems++;
            ptr += offset;
            // 跳过逗号分隔符
            while (*ptr == ',' || *ptr == ' ' || *ptr == '\t') ptr++;
        }

        if (line_elems == 0) continue; // 跳过空行
        // 第一行确定列数
        if (rows == 0) {
            cols = line_elems;
        } else if (line_elems != cols) {
            // 行列数不匹配,非法矩阵
            free(mat);
            free(line);
            return -1;
        }
        rows++;
    }
    free(line);

    if (rows == 0 || cols == 0) {
        free(mat);
        return -1;
    }

    *out_mat = mat;
    *out_rows = rows;
    *out_cols = cols;
    return 0;
}

// 使用示例
int main() {
    double *mat;
    int rows, cols;
    if (readMatrix(&mat, &rows, &cols) == 0) {
        printf("读取成功,矩阵行数:%d,列数:%d\n", rows, cols);
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                printf("%.2lf ", mat[i * cols + j]);
            }
            printf("\n");
        }
        free(mat); // 使用完释放内存
    } else {
        printf("读取失败\n");
    }
    return 0;
}

四、后续功能实现提示

  • 矩阵转置:可以新分配一个cols * rows大小的数组,将原数组i*cols + j位置的元素赋值到新数组j*rows + i位置即可
  • 矩阵乘法:若A矩阵为m行k列,B矩阵为k行n列,结果C矩阵为m行n列,C[i][j] = sum(A[i][t] * B[t][j]),t从0到k-1,按行优先索引转换即可计算。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 21:15:05