从 C 文件中读取一个浮点数数组
Reading an array of floats from a file in C
如何从 C 文件中检索浮点值数组?这是我到目前为止使用的代码,但我 运行 陷入了段错误(在我的代码中标记在哪里)。如果您看到一种不那么痛苦的方法,那也会有所帮助。
这些值存储在文件中,每个值后有一个 space,如下所示:
-667.0897114275529 544.6798599456312 -148.0586015260273 -323.4504101541069
.
// open file
FILE *fp;
fp = fopen(sig_file, "r");
if (fp == NULL){
printf("File opened incorrectly or is empty");
return 1;
}
// find file size
fseek(fp, 0L, SEEK_END);
long sz = ftell(fp);
fseek(fp, 0L, SEEK_SET);
// store file contents to f_contents
char *f_contents = 0;
f_contents = malloc(sz);
if (f_contents){
fread(f_contents, 1, sz, fp);
}
fclose(fp);
if (f_contents){
// find how many points are in the file
long pt_count = 0;
int i;
for (i=0; i<sz; i++){
if (f_contents[i] == ' '){
pt_count++;
}
}
// store points to a float array
double signal[pt_count];
char *pt;
pt = strtok(f_contents, " ");
// seg fault 11:
if (pt == NULL){
printf("error with pt");
return 1;
}
signal[0] = atof(pt);
//
for (i=1; i<pt_count; i++){
pt = strtok(NULL, " ");
signal[i] = atof(pt);
}
}
free(f_contents);
strtok()
的第一个参数必须是以 null 结尾的字符串。 fread()
不添加空终止符,即使添加了,您也没有为 f_contents
分配足够的 space 来容纳它。
所以用这段代码分配填写f_contents
f_contents = malloc(sz+1);
if (f_contents){
fread(f_contents, 1, sz, fp);
f_contents[sz] = '[=10=]';
}
fclose(fp);
If you see a less painful way of doing this that would be helpful as well.
我没有充分研究您的代码来确定段错误的来源,因为无论如何都应该重写它。我可能更倾向于做这样的事情:
// open file
FILE *fp = fopen(sig_file, "r");
if (fp == NULL){
perror("fopen");
return 1;
}
size_t sz = 0;
for (int c = getc(fp); c != EOF; c = getc(fp)) {
if (c == ' ') sz++;
}
rewind(fp);
double signal[sz];
for (size_t i = 0; i < sz; i++) {
if (fscanf(fp, "%lf", &signal[i]) != 1) {
fclose(fp);
fputs("I/O error, malformed input, or premature EOF\n", stderr);
return 1;
}
}
fclose(fp);
如果文件很长,那么一次读取所有文件而不是首先计算元素(尤其是不要将整个文件拖入内存)可能是值得的。您可以通过将值存储在更灵活的数据结构中来实现这样的一次性读取:某种链表或动态分配(并根据需要重新分配)数组。
链表需要后处理成数组形式,但您可以按原样使用动态分配的数组。您将需要使用动态分配的数组或足够大的固定大小数组以及不支持可变长度数组的 C 实现,例如 MS Visual Studio .
如何从 C 文件中检索浮点值数组?这是我到目前为止使用的代码,但我 运行 陷入了段错误(在我的代码中标记在哪里)。如果您看到一种不那么痛苦的方法,那也会有所帮助。
这些值存储在文件中,每个值后有一个 space,如下所示:
-667.0897114275529 544.6798599456312 -148.0586015260273 -323.4504101541069
.
// open file
FILE *fp;
fp = fopen(sig_file, "r");
if (fp == NULL){
printf("File opened incorrectly or is empty");
return 1;
}
// find file size
fseek(fp, 0L, SEEK_END);
long sz = ftell(fp);
fseek(fp, 0L, SEEK_SET);
// store file contents to f_contents
char *f_contents = 0;
f_contents = malloc(sz);
if (f_contents){
fread(f_contents, 1, sz, fp);
}
fclose(fp);
if (f_contents){
// find how many points are in the file
long pt_count = 0;
int i;
for (i=0; i<sz; i++){
if (f_contents[i] == ' '){
pt_count++;
}
}
// store points to a float array
double signal[pt_count];
char *pt;
pt = strtok(f_contents, " ");
// seg fault 11:
if (pt == NULL){
printf("error with pt");
return 1;
}
signal[0] = atof(pt);
//
for (i=1; i<pt_count; i++){
pt = strtok(NULL, " ");
signal[i] = atof(pt);
}
}
free(f_contents);
strtok()
的第一个参数必须是以 null 结尾的字符串。 fread()
不添加空终止符,即使添加了,您也没有为 f_contents
分配足够的 space 来容纳它。
所以用这段代码分配填写f_contents
f_contents = malloc(sz+1);
if (f_contents){
fread(f_contents, 1, sz, fp);
f_contents[sz] = '[=10=]';
}
fclose(fp);
If you see a less painful way of doing this that would be helpful as well.
我没有充分研究您的代码来确定段错误的来源,因为无论如何都应该重写它。我可能更倾向于做这样的事情:
// open file
FILE *fp = fopen(sig_file, "r");
if (fp == NULL){
perror("fopen");
return 1;
}
size_t sz = 0;
for (int c = getc(fp); c != EOF; c = getc(fp)) {
if (c == ' ') sz++;
}
rewind(fp);
double signal[sz];
for (size_t i = 0; i < sz; i++) {
if (fscanf(fp, "%lf", &signal[i]) != 1) {
fclose(fp);
fputs("I/O error, malformed input, or premature EOF\n", stderr);
return 1;
}
}
fclose(fp);
如果文件很长,那么一次读取所有文件而不是首先计算元素(尤其是不要将整个文件拖入内存)可能是值得的。您可以通过将值存储在更灵活的数据结构中来实现这样的一次性读取:某种链表或动态分配(并根据需要重新分配)数组。
链表需要后处理成数组形式,但您可以按原样使用动态分配的数组。您将需要使用动态分配的数组或足够大的固定大小数组以及不支持可变长度数组的 C 实现,例如 MS Visual Studio .