c - 从 C 中的 CSV 表获取值

标签 c csv strtok

我在 MatLab 中制作了一个矩阵并将其导出为 CSV。但我真的不知道如何在我的 C 代码中使用它。 例如,我的表格如下所示(尽管值更大且更复杂):

Height/Angle, 50, 550, 1050, 1550, 2050
5, 0.9, 0.8, 0.7, 0.6, 0.5
6, 0.8, 0.7, 0.6, 0.5, 0.4
7, 0.7, 0.6, 0.5, 0.4, 0.3
8, 0.6, 0.5, 0.4, 0.3, 0.2
9, 0.5, 0.4, 0.3, 0.2, 0.1

所以我想要的是一个接受两个参数并从表中返回相应值的函数。我有一个程序可以提供从红外传感器看到的平面的高度和角度,并根据这些值我想要相应的值。例如:在我的示例中,GetValueFromCSV(550,7); 应返回 0.6。但我不知道该怎么做。我做了一些研究 'strtok()`,但这似乎并不是我真正需要的。请帮助菜鸟。

最佳答案

。 o O(是的,仅代码答案,因为代码是不言自明的)

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

typedef struct row_tag
{
    int index;
    double *data;
} row_t;

size_t get_col_count(FILE *is)
{
    size_t col_count = 1;

    int ch;
    while ((ch = fgetc(is)) != EOF && ch != '\n')
        if (ch == ',')
            ++col_count;

    rewind(is);
    return col_count;
}

row_t* csv_read(FILE *is, size_t *cols, size_t *rows)
{
    *cols = get_col_count(is);
    *rows = 0;
    char const *origin_format = "%*[^ ,]%c";
    char const *row_header_format = "%d%c";
    char const *format = "%lf%c";
    row_t *csv = NULL;

    bool valid = true;
    for (size_t current_row = 0; valid; ++current_row) {
        csv = realloc(csv, (current_row + 1)* sizeof(row_t));
        csv[current_row].data = calloc(cols - 1, sizeof(double));

        for (size_t current_col = 0; valid && current_col < cols; ++current_col) {

            char delim;
            if (!current_col && !current_row) {
                if (fscanf(is, origin_format, &delim) != 1 || delim != ',') {
                    valid = false;
                    continue;
                }
                csv[0].index = -1;
            }
            else if (!current_col) {
                int result = -1;
                if ((result = fscanf(is, row_header_format, &csv[current_row].index, &delim)) != 2 || delim != ',') {
                    valid = false;
                    continue;
                }
            }
            else {
                if (fscanf(is, format, &csv[current_row].data[current_col - 1], &delim) != 2 || delim != ',' && delim != '\n')
                    valid = false;
            }
        }

        if (!valid)
            free(csv[current_row].data);
        else *rows = current_row + 1;
    }

    return csv;
}

void csv_free(row_t *csv, size_t rows)
{
    for (size_t row = 0; row < rows; ++row)
        free(csv[row].data);
    free(csv);
}

double csv_get_value(row_t *csv, int col_index, size_t cols, int row_index, size_t rows)
{
    size_t col;
    for (col = 1; csv[0].data[col] != col_index && col < cols; ++col);
    if (col >= cols || csv[0].data[col] != col_index)
        return 0.;

    size_t row;
    for (row = 1; csv[row].index != row_index && row < rows; ++row);
    if (row >= rows || csv[row].index != row_index)
        return 0.;

    return csv[row].data[col];
}

int main(void)
{
    char const *filename = "test.txt";
    FILE *is = fopen(filename, "r");
    if (!is) {
        fprintf(stderr, "Couldn't open \"%s\" for reading!\n\n", filename);
        return EXIT_FAILURE;
    }

    size_t cols;
    size_t rows;
    row_t *csv = csv_read(is, &cols, &rows);
    printf("Cols: %zu\nRows: %zu\n\n", cols, rows);

    fclose(is);

    // have fun with csv:
    for (size_t y = 0; y < rows; ++y) {
        printf("%2d: ", csv[y].index);
        for (size_t x = 0; x < cols - 1; ++x)
            printf("%f ", csv[y].data[x]);
        putchar('\n');
    }

    double value = csv_get_value(csv, 550, cols, 7, rows);
    printf("\n%f\n", value);


    csv_free(csv, rows);
}

输出:

Cols: 6
Rows: 6

-1: 50.000000 550.000000 1050.000000 1550.000000 2050.000000
 5: 0.900000 0.800000 0.700000 0.600000 0.500000
 6: 0.800000 0.700000 0.600000 0.500000 0.400000
 7: 0.700000 0.600000 0.500000 0.400000 0.300000
 8: 0.600000 0.500000 0.400000 0.300000 0.200000
 9: 0.500000 0.400000 0.300000 0.200000 0.100000

0.600000

关于c - 从 C 中的 CSV 表获取值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52644444/

相关文章:

从 C : errors 调用 Lua 脚本

c - 存储在数组中的自由结构

c - 我怎样才能实现像程序这样的功能?

c++ - 此代码生成段错误。我哪里出错了?

javascript - 如何在javascript中将csv文件中的数据保存为字符串?

c - 为什么用 C 语言打印时会出现这个空行?

c - 如何在 C 中打印函数参数?

c - 逐行读取多个数组的输入,而不知道要给出的输入数量

python - 使用 pandas read_csv 缺少数据

python - 使用 Pandas 读取大文本文件