In Matlab is one command, but I need to write some simple function in C (or C actually, but it doesn't matter). My goal now is to create three "double" arrays, that are taken form a table file. The file looks like this (QEOS.txt):
T rho P
11.605 2.51188643150958e-13 4.28547303990553e-16
11.605 3.16227766016838e-13 4.28547303990553e-16
11.605 3.98107170553497e-13 4.28547303990553e-16
11.605 5.01187233627271e-13 4.28547303990553e-16
11.605 6.30957344480194e-13 4.28547303990553e-16
11.605 7.94328234724282e-13 4.28547303990553e-16
11.605 1e-12 4.28547303990553e-16
11.605 1.25892541179417e-12 4.28547303990553e-16
14.6098294038713 2.51188643150958e-13 5.45304484892599e-16
14.6098294038713 3.16227766016838e-13 5.45304484892599e-16
14.6098294038713 3.98107170553497e-13 5.45304484892599e-16
14.6098294038713 5.01187233627271e-13 5.45304484892599e-16
14.6098294038713 6.30957344480194e-13 5.45304484892599e-16
...........
And I want the first column to become a variable "T", the second to be "rho" and the third "P". Shouldn't be hard at all, right? So I have:
#include <stdio.h>
#include <stdlib.h>
struct threeNum{
double n1, n2, n3;
};
int main(){
int n;
struct threeNum num;
double P,T,rho;
FILE *fptr;
fptr = fopen("QEOS.txt","r");
for(n = 1; n < 25; n){
fread(&num, sizeof(struct threeNum), 1, fptr);
printf("n1: %f \tn2: %f \tn3: %f \n", num.n1, num.n2, num.n3);
}
fclose(fptr);
T=num.n1;
rho=num.n2;
P=num.n3;
return 0;
}
The "25" is just ab example. In any case, the code prints 0.000's and random garbage. What's wrong? P.S: And I get "** stack smashing detected **: terminated Aborted (core dumped)"
CodePudding user response:
As pointed out in the comments you must use text based functions like fscanf
, as opposed to binary ones such as fread
, when reading formatted text.
You should always test the return values of library functions as most of them can fail with dramatic results (program crashes or misleading output).
Note that
T=num.n1;
rho=num.n2;
P=num.n3;
has no effect in this program.
Suggestion: use fgets
and sscanf
for more control, reading line by line.
A quick example:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
double P, T, rho;
FILE *fp = fopen("QEOS.txt", "r");
if (!fp) {
perror("fopen");
return EXIT_FAILURE;
}
char line[512];
if (!fgets(line, sizeof line, fp) || !strstr(line, "T rho P")) {
fprintf(stderr, "Invalid or missing header.\n");
return EXIT_FAILURE;
}
while (fgets(line, sizeof line, fp)) {
if (3 == sscanf(line, "%lf%lf%lf", &T, &rho, &P)) {
printf("n1: %f\tn2: %e\tn3: %e\n", T, rho, P);
}
}
fclose(fp);
}