Parsing Integer and Float Values of a Text File wi

2019-07-03 16:09发布

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.

标签: c parsing scanf
3条回答
放我归山
2楼-- · 2019-07-03 16:54

Your format string contains commas that don't exist in the input. That said, you should use %lf to parse floating point numbers into double and %lu to parse into uint64_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.

查看更多
爱情/是我丢掉的垃圾
3楼-- · 2019-07-03 16:57

If you always expect a single space between arguments you can simply your format string and obviate the need for atoi, atof:

while(fgets(str,512,fp)!= NULL)//read file line by line
{
    char *tokenstring = str;
    uint64_t netrx,nettx,vbd_rd,vbd_wr;
    char g[10];
    double cpu, mem;
    long int c, d, e, f;
    sscanf(tokenstring, "%s %lf %lf %lu %lu %lu %lu", g, &cpu, &mem, &nettx, &netrx, &vbd_rd, &vbd_wr);
    printf("%s %f %f %ld %ld %ld %ld\n",g,cpu,mem,netrx,nettx,vbd_rd,vbd_wr);
}
fclose(fp);
查看更多
看我几分像从前
4楼-- · 2019-07-03 17:03

scanf is designed to parse numbers so there is no need to use atoi, so just use sscanf with proper parameters

int result = sscanf(tokenstring, "%s %lf %lf %lld %lld %lld %lld",g, &cpu, &mem, &netrx, &netrx, &vbd_rd, &vbd_wr);
assert( result == 7 ) ;
查看更多
登录 后发表回答