-1

C++ Programmer here , need a quick solution for problem below.

I need to carry out following subtraction where input is taken from a file and desired numbers are stored in variables. However printf() is showing 0 as the value.

#include<stdio.h>

main()
{   system("clear");
    system("cat /proc/meminfo | grep MemTotal");
    system("cat /proc/meminfo | grep MemFree ");
    int a=system("cat /proc/meminfo | grep MemTotal | grep -Eo [0-9]+");
    int b=system("cat /proc/meminfo | grep MemFree | grep -Eo [0-9]+");
    int c=a-b;
    printf("%d \n",c);
}

Output is as following:

MemTotal:        3913212 kB
MemFree:         1769672 kB
3913212
1769388
0 

Moreover is there a way to supress output from 7th and 8th line in code as i just need them to store in variables.

Edit : Fixed long int.

Thanks

Abhinav Gauniyal
  • 7,034
  • 7
  • 50
  • 93

2 Answers2

2

Sample ( tested ) of popen.

#include <stdio.h>

int main(){
    system("clear");
    system(" grep MemTotal /proc/meminfo");
    system(" grep MemFree /proc/meminfo");

    int totalMem=0 , freeMem=0;
    FILE *fp =  popen("grep MemTotal /proc/meminfo | grep -Eo [0-9]+", "r");
    FILE *fp1 = popen("grep MemFree /proc/meminfo | grep -Eo [0-9]+", "r");
    fscanf(fp, "%d", &totalMem);
    fscanf(fp1, "%d", &freeMem);
    printf("%d \n",totalMem-freeMem);
    pclose(fp);
    pclose(fp1);
}
BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70
1

/proc/meminfo is a special file, mapped from the kernel into userspace. the easiest way to access such information is .. to not parse that file but use a systemcall instead:

// build: cc -o mratio-si mratio-si.c
// usage: ./mratio-si
#include <sys/sysinfo.h>
#include <stdio.h>

int main() {
    struct sysinfo si;
    if (sysinfo(&si) == 0) {
        printf("%d/%d (%.2f)\n", si.freeram, si.totalram,.
            (float)si.freeram/(float)si.totalram);
    };
    return 0;
}

or, since we have a real programming-language at hand, parse /proc/meminfo ourselves:

// build: cc -o mratio-parse mratio-parse.c
// usage: ./mratio-parse < /proc/meminfo
#include <stdio.h>
#include <string.h>

int main(int argc, char* argv[]) {

    const char MEMTOTAL[] = "MemTotal:"; const char MEMFREE[] = "MemFree:";
    long val, memfree = 0, memtotal = 0;
    char buf[256]; void* ignore; int ok = 0;

    for (; ok != EOF && !(memfree > 0 && memtotal > 0); ){
        ok = fscanf(stdin, "%255s %d %*s\n", buf, &val, ignore);
        if (ok == 0) { return 1; }
        if (strncmp(buf, MEMTOTAL, sizeof(MEMTOTAL)-1) == 0) {
            memtotal = val;
        } else if (strncmp(buf, MEMFREE, sizeof(MEMFREE)-1) == 0) {
            memfree = val;
        }
    }

    if (memfree == 0 || memtotal == 0) {
        perror("parse error, did not find 'MemFree' or 'MemTotal'\n");
        return 1;
    }

    printf("%d/%d (%.2f)\n", memfree, memtotal, (float)memfree/(float)memtotal);
    return 0;
}

in any case, using popen() is obviously possible as well but has some kind of overhead (and consistency problems because there is some time between the first grep and the last invocation of it, invoking grep itself changes /proc/meminfo because it eats, well, memory).

akira
  • 6,050
  • 29
  • 37