Thread: Question on using fgets

  1. #1
    Registered User
    Join Date
    Sep 2008
    Posts
    60

    Question on using fgets

    Hey guys,
    Can you take a look at my code and tell me what is wrong?
    I am trying to use fgets to print the first n characters of each line of a file.

    When this function gets called 3 strings are passed to it, the command (which is irrelevant to this example). The maximum length of each line and the file name to be opened for reading.

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    int trunc(char *command, char *maxLen, char *fileName)
    {
    	FILE *finp;
    	int i = atoi(maxLen);
    	char line[i];
    	if((finp = fopen(fileName, "r")) == NULL) {
    		printf("Error - Cannot open file: &#37;s\n\n", fileName); 
    		return 1;	
    	}
    	while(fgets(line, i, finp) != NULL) {
    		printf("%s", line);
    	}
    	printf(" \n");
    	if(fclose(finp) == EOF) {
    			printf("Error in closing file\n");
    	}
    	return 0;
    }
    For ouput, I get every line of the text file completely and not n characters long as i would like(or i in this example)
    Any ideas ?
    Last edited by gp364481; 10-17-2008 at 08:04 AM.

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    If fgets() doesn't read the entire line, then it will continue where it left of on the next line. For example, a loop of fgets(buffer, 3, infile) on
    ABCDEF\n
    will read ABC, but DEF\n will remain in the input file until it has been read from the file in some way. In your case, fgets() will read it in the next iteration of the loop.

    There are two solutions that come to mine immediately:
    1. Read using fgets much longer line (make sure you have a long buffer), and truncate to n chars before printing.
    2. Read using fgets for up to n characters. If the buffer doesn't end up with a newline ('\n') in it, read the remainder of the line up to, inclusive, the '\n' character.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    Sep 2008
    Posts
    60
    Hey, thanks for your reply. I got it to work now.
    Revised code:

    Code:
    int trunc(char *command, char *maxLen, char *fileName)
    {
    	FILE *finp;			/*file pointer for input file*/
    	int i = atoi(maxLen);
    	char line[MAXLEN];
    	int p;
    	if((finp = fopen(fileName, "r")) == NULL) {						/*open file for reading*/
    		printf("Error - Cannot open file: %s\n\n", fileName); 
    		return 1;													/*exit function if it fails*/
    	}
    	while(fgets(line, MAXLEN, finp) != NULL) {
    		for(p=0; p<i-1; p++) { 
    		printf("%c", line[p]);
    		}
    		printf(" \n");
    	}
    	printf(" \n");
    	if(fclose(finp) == EOF) {
    		printf("Error in closing file\n");
    	}
    	return 0;
    }
    added a forloop to just print the first i characters.
    Is that a good solution? Is there a better way to do that?

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Depends on how you define "better"...

    I prefer either of my two solutions. The first one is similar to yours, but instead of calling printf many times, you just put a '\0' in the string where you no longer want to print any more.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    Another problem with your new solution is that if a line is read and it is shorter than i, you will run off the end of the string in your for() loop.

    And why "p < i-1"?
    Mainframe assembler programmer by trade. C coder when I can.

  6. #6
    Registered User
    Join Date
    Sep 2008
    Posts
    60
    ok matt and dino,
    thanks for your replies
    I think this works better

    Code:
    while(fgets(line, MAXLEN, finp) != NULL) {
    	line[i-1] = '\0';
    	printf("%s", line);
    	printf(" \n");
    }
    the reason I have i-1 is because I am to print the first n characters of a list including a new line character. so i leave the last spot for '\n'.

  7. #7
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    What happens if maxLen is 20 and the actual line length is 2? Do you think that fix will produce the correct result?
    Mainframe assembler programmer by trade. C coder when I can.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. another do while question
    By kbpsu in forum C++ Programming
    Replies: 3
    Last Post: 03-23-2009, 12:14 PM
  2. fgets question
    By mattyg in forum C Programming
    Replies: 2
    Last Post: 12-01-2008, 04:25 AM
  3. Question...
    By TechWins in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 07-28-2003, 09:47 PM
  4. fgets problem (i think)
    By GanglyLamb in forum C Programming
    Replies: 3
    Last Post: 03-19-2003, 11:19 AM
  5. opengl DC question
    By SAMSAM in forum Game Programming
    Replies: 6
    Last Post: 02-26-2003, 09:22 PM