0

First, I'm totally beginner in linux and C language, I can't relate C to c++ or java much when it comes to strings!. I'm using Fedora16 - linux - and I want to read a proc/[pid]/status file to get specific information from it, such as PPID and state, then I should print these info on the screen - command line terminal-. This must be done by writing a c script in gedit. My only issue is that I'm new to c, and dealing with strings in c seems very frustrating to me! I have already opened the file and view it on my terminal by executing the c file. Is there any possible way to store the whole content in one string variable and then I can tokenize it and store the chunks of data as in string array not char array, then I know where my wanted data is in the array and I can access it?

Here is my code though

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

void main()
{


const char line[200];
const char junk[200];

FILE *file = fopen("/proc/14/status", "r");

// while not end of the file
while(!feof(file)) {

fscanf(file,"%s",line); //Get text into line array

printf("%s\n", line);

//fscanf(file,"%[ \n\t\r]s",junk); //Remove any 'white space' characters

               }//end while

fclose(file);

}

Output On Terminal:

enter image description here

AMH9
  • 179
  • 1
  • 4
  • 20
  • 1
    http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong – cadaniluk Oct 17 '15 at 08:49
  • 1
    For a general idea about how to write this kind of code, see [my answer here](http://stackoverflow.com/questions/32724946/change-niceness-of-all-processes-by-niceness/32726172#32726172) –  Oct 17 '15 at 08:50
  • 1
    For strings in C, it's actually extremely simple: they do not exist. C only knows *string literals* that translate to an array of `char` with a `0` at the end and just evaluate to a pointer to their first `char`. So, think pointers and arrays, not strings. BTW, the term *c-string* sometimes used means exactly that: an array of `char` with zero at the end. `string.h` has a lot of functions for basic operations on that kind of "strings", just look at an overview. –  Oct 17 '15 at 08:51
  • 2
    And as a last remark: **never** use a plain `%s` in `scanf()`, it will eventually overflow any buffer and is a security risk. –  Oct 17 '15 at 08:55

1 Answers1

2

There are two things wrong initially

  1. line should not be const.
  2. while (!feof(file)) is almost always wrong.

The fix involves doing something like

while (fscanf(file, "%199s", line) == 1)

which will loop until there is no more data and will prevent overflowing line.

This will fix something, the other thing is rather complicated, first try using fgets() instead if fscanf(), it will consume lines from the file including the '\n' and the embedded white spaces

while (fgets(line, sizeof(line), file) != NULL)

then you can try sscanf() checking it's return value to ensure that it succeeded.

From the content of /proc/self/status you can see that strchr() would do a good job in splitting the lines in the interesting parts.

This is an example:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

int
main(void)
{
    FILE *file;
    char line[100];
    file = fopen("/proc/self/status", "r");
    if (file == NULL)
        return -1; /* Failure to open /proc/self/stat -- very unlikely */
    while (fgets(line, sizeof(line), file) != NULL)
    {
        char *tail;
        char *key;
        char *value;
        tail = strchr(line, '\n');
        if (tail != NULL)
            *tail = '\0'; /* remove the trailing '\n' */
        tail = strchr(line, ':');
        if (tail != NULL)
        {
            tail[0] = '\0';
            key = strdup(line);
            if (key == NULL)
                continue;
            tail += 1;
            while ((tail[0] != '\0') && (isspace((int) tail[0]) != 0))
                tail++;
            value = strdup(tail);
            if (value != NULL)
            {
                fprintf(stderr, "%s --> %s\n", key, value);
                /* You could do something now with key/value */
                free(value);
            }
            free(key);
        }
    }
}
Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97
  • That last line when every key and value are saved in a char variable helped me a lot! now I can print the specific info that I want, thank you. – AMH9 Oct 17 '15 at 10:49