2

I am having a requirement to read a file line by line through a c program. I know I can do it very straight by using a FILE pointer and using fgets (if by fixed length string) or fgetc (if by character by character). The only point here to note is that the length of a line in the file can be different. So , if i am using

char *fgets(char *__restrict s, int n, FILE *__restrict stream); 

I do not know the value of "int n" here since it can vary from line to line in the file.

I searched for an answer for this query but i got to know the usage of getline function which is c++ function. The only way for me is to read each character until i encounter a '\n' and get that copied to a string.

Is there any other way to do this straight in a c program ?

Shri
  • 27
  • 1
  • 8
  • 2
    Possible duplicate of [How to read a line from file?](http://stackoverflow.com/questions/286123/how-to-read-a-line-from-file) – piyushj Sep 29 '16 at 08:43
  • 2
    Use [getline in POSIX C](https://linux.die.net/man/3/getline) – BLUEPIXY Sep 29 '16 at 08:46
  • The question in the link specifies fixed length of input lines in the file. My question here is that i do not know the length of the line in the file. – Shri Sep 29 '16 at 08:46
  • @BLUEPIXY I dont find a man page for getline. So ideally i don't find a way to use it in my program. I am using HPUX machine – Shri Sep 29 '16 at 08:48
  • Are you using the GCC? – BLUEPIXY Sep 29 '16 at 08:50
  • No I dont use the GCC compile. I use cc compiler. Is there any way by which we can do this without the usage of getline ? – Shri Sep 29 '16 at 08:57
  • 1
    [like this](http://stackoverflow.com/a/27369716/971127) – BLUEPIXY Sep 29 '16 at 09:01
  • @BLUEPIXY Thats possible the function definition of the getline and getdelim functions. I will see if i can use that as my c standard doesnt support getline function. Thanks for your comment. – Shri Sep 29 '16 at 09:14

2 Answers2

0

Check this ->explanation (possible duplicate question) The getline function is documented -> here

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>

int
main(void)
{
    FILE *fp;
    char *line = NULL;
    size_t len = 0;
    ssize_t myread;

   fp = fopen("/etc/motd", "r");
    if (fp == NULL)
        exit(EXIT_FAILURE);

   while ((myread = getline(&line, &len, fp)) != -1) {
        printf("Retrieved line of length %zu :\n", myread);
        printf("%s", line);
    }

   free(line);
    exit(EXIT_SUCCESS);
}
Community
  • 1
  • 1
P.Bra
  • 264
  • 1
  • 12
  • Thanks for your comments. My project uses cc compiler in Unix machine to compile the c programs. In the explanation link that you shared, the code uses character by character reading using fgetc which i already stated in my question as the only way around. But before that i just wanted to know if there was any straight function to do this operation. – Shri Sep 29 '16 at 09:04
  • @Shri there is public domain implementation of getline function, you could check [here] (http://stackoverflow.com/questions/12167946/how-do-i-read-an-arbitrarily-long-line-in-c/12169132#12169132) hope this helps. – P.Bra Sep 29 '16 at 09:23
  • @P.Bra Sure I will take a look at it . Thank you :) – Shri Sep 29 '16 at 14:20
0

I do not know the value of "int n" here since it can vary from line to line in the file.

The above and other discussion implies OP wants code that auto-sizes the buffer to whatever the line length may be. fgets() does the job fine if you are willing to accept a max length. Read the line and then copy in to a right-sized buffer.

  #define BUF_SIZE 1000
  char buf[BUF_SIZE];

  while (fgets(buf, sizeof buf, stream)) {

    // Add long line detection here if desired

    char *s = strdup(buf);
    foo(s);
  }

If code does not want to impose any maximum length, IMO, that is a weak design. Certainly lines can be very long and BUF_SIZE above should be a very generous value, but to allow code to handle lines of any length is to give control of the program to external forces be it a file or user input. That is the basis of a hacker exploit. The given application should have a liberal upper bound of the acceptable line length. fgets() provides that - although it does have other weaknesses. The common *nix getline() allows external forces to cause your program to consume up to SIZE_MAX byte in one call - not defensive code.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • Thank you . Just a curious question what happens if i use fscanf in this case ? My whole problem gets solved if i use fscanf but I know thats a bad programming to use fscanf and feof to read a line. – Shri Sep 29 '16 at 14:29
  • @Shri Using `fscanf()` to read a _line_ of input is not the best tool in the shed for this task. `fscanf()` could be use to read a line, in conjunction with other code. Something like `char buf[100]; n = fscanf(stream, "%99[^\n]", buf); if (n == 0) buf[0] = 0; if (n==EOF) exit_loop else fgetc(stream);` It is nearly equivalent, but more complicated. Simpler uses of `fscanf()` fail to account for all possible inputs situations - IOWs, not robust code. – chux - Reinstate Monica Sep 29 '16 at 15:50