I am using fgets()
to read lines from popen("ps -ev", "r")
and I cannot find out how to know if fgets()
reads a line partially or fully, and if partially how to read/throw away the excess.
When reading each line from popen()
, I am reading in the first 1024 characters and getting the information I need from that, which works perfectly fine. The issue arises when the lines are greater than 1024 characters and then the next line I read is a continuation of the previous line, which is not in the format I need (that being the value of each column at the beginning of each line). If I can know if I only partially read a line (that being the line has 1024 or more characters, I want to read and throw away every 1024 characters until it reaches the end. Once at the end, I can call fgets()
again and this time it will read from the beginning of the next line rather than the continuation of the previous line.
I know that fgets()
reads up until it either finds a newline or until it reaches the provided limit, and then continues reading the remaining part of the line. I have tried checking that the last character is '\0' and that the second last character in the line is '\n', but that does not work. I will post that code below in case that helps.
If you run the code, you will see LINE: num S num:num.num ...
(where num
is a number) which is what each line should begin with. Some lines will instead look something like LINE: AAAAAAQAAABMAAAAQAAAAAAAAAAMAAAAFAAAAEAAAAAAAAAADAAAACwAAABA...
. These are the lines that are excess from the previous line, and these are the ones causing the issues since they are not in the correct format.
Any and all help is highly appreciated.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#define NEWLINE() printf("\n");
#define DIVIDER() printf("============================================================================\n");
#define PL(l) printf("LINE: %s\n", l);
int const MAX_PROCESSES = 20;
int const BUFFER_SIZE = 1024;
int exhaustedLine(char* line) {
if (line[sizeof line - 1] == '\0' && line[sizeof line - 2] != '\n') {
printf("n:%c 0:%c\n", line[sizeof line - 2], line[sizeof line - 1]);
NEWLINE();
return -1;
}
return 0;
}
int main(int argc, char const *argv[]) {
FILE* fp = popen("ps -ev", "r");
char buf[BUFFER_SIZE];
char* line = (char*)1;
while (line) {
DIVIDER();
line = fgets(buf, BUFFER_SIZE, fp);
PL(line);
if (exhaustedLine(line) != 0) {
printf("END OF LINE\n");
}
}
return 0;
}
fgets
documentation or reference (like e.g. this one) it will tell you that if the full line was read, the last character would be a newline. – LeukoexhaustedLine
,sizeof line
is the size of the char pointer, so it's not what you want. If the line was not terminated by a newline,line[n - 1]
will hold the null terminator andline[n - 2]
will hold a non-null character other than a newline. – Kinghood