我正在尝试读取包含加速度数据(x、y、z 轴)的 .csv 文件。文件格式如下:
BBD66,0.000125,0,0.000875
BBD66,0.000125,0,0.000125
BBD66,0,-0.000125,-0.000625
BBD66,-0.00025,0.000125,0.000125
BBD66,0,0,0.000875
BBD66,0,0,0.000125
BBD66,0.000125,0,-0.000125
BBD66,0,0,0.00025
BBD66,-0.000125,0,0.000375
依此类推,直到第 8192 行。
我创建了一个包含 819 个随机数(从 0 到 8191)的数组
perm
,因此当我读取文件时,我只会保存与该 perm
数组上的数字对应的行。
代码如下(不包括生成数字的代码,因为这些行没有问题):
#define MAXCHAR 1024
#define N 8192
#define p 819
/////////////////////////// READING SAMPLES FILE ///////////////////////////
FILE *file_accel;
// Allocate the array of pointers
char **x_samples = (char **)malloc(p * sizeof(char *));
char **y_samples = (char **)malloc(p * sizeof(char *));
char **z_samples = (char **)malloc(p * sizeof(char *));
// Allocate rows (max length 15 characters, including \0)
for (int i = 0; i < p; ++i) {
x_samples[i] = (char *)malloc(15 * sizeof(char));
x_samples[i] = '\0';
y_samples[i] = (char *)malloc(15 * sizeof(char));
y_samples[i] = '\0';
z_samples[i] = (char *)malloc(15 * sizeof(char));
z_samples[i] = '\0';
}
file_accel = fopen("report_accelerometer_BBD66_80Hz_full.csv", "r");
if (!file_accel) {
printf("Can't open file\n");
return 1;
}
// Here we have taken size of
// array 1024 you can modify it
char buffer[MAXCHAR];
int row = 0;
int column = 0;
// compare each perm[i] with the corresponding readed line in the file
for (int i = 0; i < p; i++) {
while (fgets(buffer, MAXCHAR, file_accel)) {
if (row != perm[i]) {
row++;
continue;
} else {
column = 0;
// Splitting the data
char *value = strtok(buffer, ",");
if (i == 818) {
printf("STOP RIGHT HERE TO SEE WHAT IS GOING ON\n\n");
}
printf("Data %d (row %d): ", i, perm[i]);
while (value) {
// Column 1
if (column == 0) {
value = strtok(NULL, ",");
column++;
continue;
}
// Column 2
if (column == 1) {
x_samples[i] = value;
printf("%s ", x_samples[i]);
}
// Column 3
if (column == 2) {
y_samples[i] = value;
printf("%s ", y_samples[i]);
}
// Column 4
if (column == 3) {
z_samples[i] = value;
printf("%s ", z_samples[i]);
}
// printf("%s ", value);
value = strtok(NULL, ",");
column++;
}
printf("\n");
row++;
}
break;
}
}
// Close the file
fclose(file_accel);
/////////////////////////// READING SAMPLES FILE ///////////////////////////
free(perm);
// free memory
for (int i = 0; i < p; i++) {
free(z_samples[i]);
free(y_samples[i]);
free(x_samples[i]);
}
free(x_samples);
free(y_samples);
free(z_samples);
当我运行代码时,这会显示在输出中:
Data 712 (row 6879): 0 0 0
Data 713 (row 6897): 0.000125 0 0
Data 714 (row 6908): 0 0 -0.000125
Data 715 (row 6924): 0 0 -0.000375
Data 716 (row 6933): 0.0
[Done] exited with code=3221226356 in 0.288 seconds
当我调试它时,它会打印出每一行,直到数据818,如下所示:
Data 814 (row 8170): 0 0 0.000125
Data 815 (row 8176): -0.000125 -0.000125 -0.0015
Data 816 (row 8180): 0 -0.000125 0
Data 817 (row 8183): 0.000125 0.000125 -0.00025
STOP RIGHT HERE TO SEE WHAT IS GOING ON
Data 818 (row 8186): 0 0 0.000125
但是当它到达这里的第一个空闲行时:
for (int i = 0; i < p; i++) {
free(z_samples[i]);
free(y_samples[i]);
free(x_samples[i]);
}
几步之后,显示:
发生异常。未知信号。
释放分配的内存时出现问题。但我不知道是什么。
这没有任何意义:
x_samples[i] = (char *)malloc(15 * sizeof(char));
x_samples[i] = '\0';
这是一个厚颜无耻的错误,因为
'\0'
实际上是一个有效的空指针常量,因此它将“在编译器的雷达下”通过。实际上,您丢弃了分配的内存并将其保留为泄漏,让指针变成空指针。
您可能打算将指向的 contents 设为 null:
x_samples[i][0] = '\0';
避免此特定错误的另一个小解决方法可能是发明类似的东西:
#define NUL ( (char){'\0'} )
它仍然是一个编译时计算表达式(复合文字),但不再是一个整数常量表达式,因此它也不是一个有效的空指针常量。作为奖励,您将获得一个类型为
char
的字符常量。
x_samples[i] = NUL; // wrong, constraint violation & compiler error/warning
x_samples[i][0] = NUL; // ok
至于如何读取乱码Windows错误代码,十进制代码3221226356并没有告诉jack。转换为十六进制,它变成 0xC0000374,Windows 错误代码往往以 0xC000 开头...一旦转换为十六进制,我们就可以 google 一下,0xC0000374 具体来说是堆损坏,这有助于在跟踪错误时了解情况。