I want to parse such a file with these fields into integer and float variables,I tried to do this using fscanf,strtok,sscanf. But none of them works!
Some lines of the file :
fed18 5.7 12.7 144997 8087 267345 100776
fedora18 24.9 25.3 253566 10501 126282 118157
fed18 5.9 12.7 145005 8094 267345 100785
fedora18 23.3 25.3 253576 10507 126282 118169
fed18 6.2 12.7 145013 8100 267345 100789
Running the following code returns wrong values! I don't know what's the problem as I search, everybody use such this code and it works properly for them!
while(fgets(str,512,fp)!= NULL)//read file line by line
{
char *tokenstring = str;
uint64_t netrx,nettx,vbd_rd,vbd_wr;
double cpu, mem;
char a[10],b[10],c[10],d[10],e[10],f[10],g[10];
sscanf(tokenstring, "%s ,%[^' '],%[^' '],%[^' '],%[^' '],%[^' '],%[^' ']",g, a, b, c, d, e, f);
cpu = atof(a);
mem = atof(b);
nettx = atoi(c);
netrx = atoi(d);
vbd_rd = atoi(e);
vbd_wr = atoi(f);
printf("%s %f %f %ld %ld %ld %ld\n",g,cpu,mem,netrx,nettx,vbd_rd,vbd_wr);
}
fclose(fp);
Here is the output:
fed18 38.000000 1.000000 0 0 0 0
fedora18 38.000000 1.000000 0 0 0 0
fed18 38.000000 1.000000 0 0 0 0
fedora18 38.000000 1.000000 0 0 0 0
fed18 38.000000 1.000000 0 0 0 0
I edited the original text file with a bash script and using awk
,....
The original lines were in this format:
fed18 --b--- 3616 6.3 1052640 12.7 1052672 12.7 3 1 125864 6023 1 0 254349 93082 7412662 4730752 0
fedora18 --b--- 4711 2.4 2101216 25.3 2101248 25.3 3 1 249151 8636 1 0 126083 113505 3306934 5992656 0
I selected some columns using a bash script. maybe this caused the problem!
I commented the lines of using function atoi
or atof
but still output wrong values.
Your format string contains commas that don't exist in the input. That said, you should use
%lf
to parse floating point numbers intodouble
and%lu
to parse intouint64_t
.Note that you might run into trouble when the current locale isn't English because that influences which character C expects as a decimal point. Use
setlocale(LC_NUMERIC, "C");
to fix that.If you always expect a single space between arguments you can simply your format string and obviate the need for
atoi
,atof
:scanf is designed to parse numbers so there is no need to use
atoi
, so just use sscanf with proper parameters