Thread: Best way to read lines out of a text file

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Linux is where it's at movl0x1's Avatar
    Join Date
    May 2007
    Posts
    72

    Best way to read lines out of a text file

    Hi. If i've got a text file like:

    --------------
    filename1\n
    filename2\n
    filename3\n
    --------------

    and want to read a line at a time out of that file into say a buffer

    is this the an ok way to do that? or is there a better way?

    Code:
    char buffer[100];
    FILE *fp;
    int c;
    
              do {
                     c = fscanf(fp, "%s", filename);
                     dosomething_withfilename();
              } while (c != EOF);

    Oh, and am I right in assuming that fscanf appends NULL to the ends of the lines it
    reads into the buffer?
    thanks

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    fscanf() definitely won't do what you want. You want to use fgets(), but that is limited to a specifically sized buffer. That might be okay for your purposes. If you want to be able to handle arbitrarily long lines, it gets more complicated.

  3. #3
    Linux is where it's at movl0x1's Avatar
    Join Date
    May 2007
    Posts
    72
    But wouldn't the above code read those three lines into filename[] one
    at a time in the loop?


    I was thinking that each time fscanf was called it would read up to the \n,
    and then append a null creating a string in memory.

    thanks

  4. #4
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by movl0x1 View Post
    But wouldn't the above code read those three lines into filename[] one
    at a time in the loop?

    thanks
    No, because fscanf() doesn't do that. "%s" means "read a string of non-whitespace characters." It does NOT mean "read an entire line." So if the line of input has a space in it (which it probably does), you will only get the data up to that space.

  5. #5
    Linux is where it's at movl0x1's Avatar
    Join Date
    May 2007
    Posts
    72
    But if it was a file that my program created, and was
    guaranteed to have lines without space in them it would work.


    Guess I should've types 'man fscanf'. I haven't used fcanf much, up
    till now.

    But I think fgets(), as you suggested, is better to use.

    Thank you for your help
    Last edited by movl0x1; 05-29-2007 at 11:30 AM.

  6. #6
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by movl0x1 View Post
    But if it was a file that my program created, and was
    guaranteed to have lines without space in them it would work.
    But the first time a user tries to use it under conditions that violate those assumptions, everything breaks. The word people use for this is "brittle." Sure, you can build your house on a foundation of glass but once the tiniest little crack develops the whole things comes crashing down.

  7. #7
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    > But if it was a file that my program created, and was
    > guaranteed to have lines without space in them it would work.

    That's something that will almost never be the case. If this is for your file splitting program I think you are making too many assumptions. If you actually tried to enforce this (just so you can use fscanf()!) then your program's output is useless to human readers. And I think split was developed with a wide scope of applications in mind.

    There's lots of ways to read a line that would "work" depending on how detailed your case is. fgets() is a hero in most places. But if you're just spitting out n lines of a file then maybe this is easiest, considering your progress
    Code:
    int c;
    size_t lncount = 1;
    for( ; lncount < nlines; )
    {
       c = fgetc( in );
       if( c != EOF )
       {
          fputc( c, out );
          if( c == '\n' )  lncount++;
       }
    }

  8. #8
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Look at your loop again closely. Even if fscanf() doesn't read anything, you're still calling your function. It's not until after your function is called that you break out of the loop. That's a bad thing.

    Something like this would probably be better:
    Code:
    char buf[BUFSIZ];
    char *p;
    
    while(fgets(buf, sizeof(buf), fp))
    {
      if((p = strchr(buf, '\n')))    // If there's a newline
        *p = '\0';                   // Get rid of it
      do_something();
    }
    Last edited by itsme86; 05-29-2007 at 11:37 AM.
    If you understand what you're doing, you're not learning anything.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Inventory records
    By jsbeckton in forum C Programming
    Replies: 23
    Last Post: 06-28-2007, 04:14 AM
  2. Basic text file encoder
    By Abda92 in forum C Programming
    Replies: 15
    Last Post: 05-22-2007, 01:19 PM
  3. C++ std routines
    By siavoshkc in forum C++ Programming
    Replies: 33
    Last Post: 07-28-2006, 12:13 AM
  4. read multiple lines from a file
    By YankeePride13 in forum C Programming
    Replies: 2
    Last Post: 11-10-2005, 10:30 PM
  5. Replies: 5
    Last Post: 02-01-2003, 10:58 AM