Parsing output error

Hi i didn't know if i should post it here or in the linux section but anyway here it goes. I have an application where monitoring other application that im running using the top command in linux. What i want to do is parse that top batch output so i can retrieve the CPU percentage. here is my code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
FILE *fpipe;
char *command[150];
snprintf(command,sizeof command,"top -b -p%d",pd->pid," -n1");
char buff[530];
size_t result_read;
if (!(fpipe = (FILE*)popen(command,"r"))){
    // if fpipe is NULL
    perror("Process Stopped: cannot read pipe");
    break;
}

int fd = fileno(fpipe);
while ((result_read = read(fd, buff, sizeof (buff)))>0){
	if (result_read < 0){
	    perror("Problem while reading");
	    printf("Error while reading");
	    break;
        }
        else{
	    printf("\n\n%s\n\n", buff);
	    break;
        }
}


I've tried using sscanf() but it really didn't work, i may have been using it wrong maybe someone here can help me.

basically this is the output from the code:
1
2
3
4
5
6
7
8
9
top - 16:07:49 up 1 day,  1:11,  3 users,  load average: 6.01, 5.77, 5.41
Tasks:   1 total,   0 running,   1 sleeping,   0 stopped,   0 zombie
Cpu(s): 10.0%us, 85.7%sy,  0.0%ni,  3.4%id,  0.1%wa,  0.0%hi,  0.8%si,  0.0%st
Mem:    509312k total,   487432k used,    21880k free,     2248k buffers
Swap:  1341388k total,   261388k used,  1080000k free,    27032k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND            
17134 user      20   0  2708  908  864 S  0.0  0.2   0:00.01 Test_PointSim      
core.16257


and what i want only is the %CPU value in the second last line which in this case '0.0' any thoughts on how i can do this.
I would use a scanf.

float cpu;
scanf( "%*d %*s %*d %*d %*d %*d %*d %*s %f", &cpu );

checking the return code of scanf to ensure it parsed correctly
What flavor of Linux are you using? jsmith looks like he has a good solution but I have to be honest I think if you dug into the API a little further you'll find a function that reports exactly what you need without the need to parse the data. I know in Windows what you are doing is a matter of two maybe three functions.
There isn't an API in linux for that.

top works by reading cpu usage values from /proc/<pid>/stat for each process and dividing the difference
between successive reads by the amount of time elapsed between reads.

@jsmith
I think you went straight to line 8 of the output, and parsed that but the thing is that, the output starts right at the top on line 1, at 'top' there is all that redundant information that i don't need how would i skip that is there a quicker way of parsing through all that rather than doing...

float cpu;
sscanf(%*s %*s %*d .....

I see that you've used scanf is there a reason for that?

Thanks
If I can suggest, pass the Process ID to your program to use as a 'marker' once your program sees the PID it knows to start parsing at that line? Otherwise you may be stuck throwing out a static number of lines to get to what you want.
Thanks but i sloved it in a slightly different way. I sloved it by the locating the new line substring "\n" and looping through my buffer 8 times since the cpu usage is on the 8th line then by sscanf i pick out the cpu usage.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
FILE *fpipe;
char *command[150];
snprintf(command,sizeof command,"top -b -p%d",pd->pid," -n1");
char buff[530];
char *ptr = buff;
size_t result_read;

if (!(fpipe = (FILE*)popen(command,"r"))){
	// if fpipe is NULL
	perror("Process Stopped: cannot read pipe");
	break;
}

int fd = fileno(fpipe);
while ((result_read = read(fd, buff, sizeof (buff)))>0){
	if (result_read < 0){
		perror("Problem while reading");
		printf("Error while reading");
		break;
	}
	else{
		float cpu;
		int k = 0;
	        for (k = 0; k < 7; k++){
			ptr = strstr(ptr, "\n") +1;
		}
		sscanf(ptr, "%*d %*s %*d %*d %*d %*d %*d %*s %f", &cpu);
		printf("\n\n%f\n\n", cpu);
		printf("%s\n\n", buff);
		break;
	}
}
Topic archived. No new replies allowed.