我在 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/