Thread: Vexed by the output of my loop...

  1. #1
    Registered User
    Join Date
    Apr 2011
    Posts
    10

    Vexed by the output of my loop...

    Hi all. Another newbie C programmer here. Working through the last problem in my text, and mostly I've been able to do them all without any outside help. However, I have to say that I think I/O is my weak point for some reason. So, here I am, at the last exercise, feeling a bit defeated.

    The problem is this: write a program that displays 20 lines of an input file at a time. After 20 lines, it prompts the user whether to keep going (by entering any character) or entering 'q' to quit.

    My code looks like this:
    Code:
    #include <stdio.h>
    
    int main (void)
    {
    	char linebuf[200], inputName[64];
    	FILE *in;
    	char command = 'a';
    	int i;
    
    	printf("Enter name of file to be copied: ");
    	scanf("%63s", inputName);
    	printf("\n");
    	
    	if ( (in = fopen(inputName, "r")) == NULL) {
    		printf("Can't open %s for reading.\n", inputName);
    		return 1;
        }
    
    	do {
    		for (i = 0; i < 20; ++i) {
    			fgets(linebuf, 20, in);
    			printf("%s", linebuf);
    		} 
    		
    		printf("Enter a character (q to quit): ");
    		scanf("%c", &command);
    
    	} while (command != 'q');
    		
    
    	return 0;
    }
    The problem with the output is that the 'for' loop executes 20 times, prints the message "Enter a character . . ." but does not pause to wait for input, but instead jumps right back into the 'for' loop another 20 times. After which it does pause and wait for input.

    I suppose I would like to learn this, so a clue or a pointer (not the C kind, the pedagogical kind) rather than a straight answer to start with would be appreciated.

    EDIT: I wanted to add that I've seen and understand an alternative solution to this problem. However, I think I would benefit from knowing what is going wrong with my solution.
    Last edited by Flint_Paper; 05-04-2011 at 02:52 PM. Reason: Caveat added.

  2. #2
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    There's probably a newline character being left in the input buffer that is causing your last scanf() to think you hit enter...
    Try following the scanf() with getchar().
    Code:
    scanf("%c", &command);
    getchar();

  3. #3
    Registered User
    Join Date
    Apr 2011
    Posts
    10
    Thanks, Tater. Although, I think you meant:

    Code:
    getchar();
    scanf("%c", &command);
    This is something I think I've not fully understood about I/O operations. I had a feeling the problem had something to do with a newline character either missing or hanging around. However, if I understood all of these functions and their behaviours correctly, I might have been able to predict the need to use getchar(). Clearly, further study by me is required...

  4. #4
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Nope, I think Tater had the correct order. fgets will read in the newline character, if one exists. scanf on the other hand, only consumes a single character when you use the %c modifier, so when you type "q<enter>", command gets assigned 'q', and the new line is still in the buffer. It's that newline that you want to "flush". There's a little article on a more robust way to do it here: Cprogramming.com FAQ > Flush the input buffer.

    You blindly call fgets in your for loop without checking it's return value. That means you don't stop at the end of a line or at the end of the file. You always call fgets 20 times, which may read nothing, then ask if they want to quit or continue. Look at the docs for fgets, and use a more appropriate control than your for loop. Something like while (i < 20 && fgets(...) != NULL). You can also check for a trailing '\n' in linebuf to determine whether you have read the entire line or only part of it.

  5. #5
    Registered User
    Join Date
    Apr 2011
    Posts
    10
    Thanks anduril. The reason I suggested a different order is that the 'q' command ceases to terminate the program when entered if the getchar() call is made before scanf.

    I will ponder some more on your suggestions and try to get a better understanding of what I'm doing here.

  6. #6
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Ahh, that's because you're using scanf to read the file name, which leaves the newline in the input buffer. So the getchar would be more appropriate right after both scanf calls.

  7. #7
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by anduril462 View Post
    Ahh, that's because you're using scanf to read the file name, which leaves the newline in the input buffer. So the getchar would be more appropriate right after both scanf calls.
    Thanks... but that's what I thought I was suggesting...

  8. #8
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Oh, I'm sure it was, but your example in post #2 used the scanf("%c", &command), so I think the OP got confused (and myself a bit too).

  9. #9
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by anduril462 View Post
    Oh, I'm sure it was, but your example in post #2 used the scanf("%c", &command), so I think the OP got confused (and myself a bit too).
    OOPS... my bad... sorry.

    ... The last problem I need today is a confused anduril on my case ...

  10. #10
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by CommonTater View Post
    ... The last problem I need today is a confused anduril on my case ...
    Not a very difficult thing to accomplish on days like today.

  11. #11
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by anduril462 View Post
    Not a very difficult thing to accomplish on days like today.
    Yeah well... leave me out of your bad days... I have plenty of those on my own! ... LOL.

  12. #12
    Registered User
    Join Date
    Apr 2011
    Posts
    10
    Actually, none of these work when I compile and run them. They all fail to end the program when I enter 'q'. The only thing that quits the program is when the getchar() call is made before the last scanf call.

    Checking the fgets return in the while conditions causes an infinite loop.

    Maybe I'm still confused (I also experience this easily )

  13. #13
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    Post the current problematic code.

  14. #14
    Registered User
    Join Date
    Apr 2011
    Posts
    10
    Code after modifying according to Tater's original post:

    Code:
    //This one fails to quit when 'q' is entered
    
    #include <stdio.h>
    
    int main (void)
    {
    	char linebuf[200], inputName[64];
    	FILE *in;
    	char command = 'a';
    	int i;
    	
    	printf("Enter name of file to be copied: ");
    	scanf("%63s", inputName);
    	printf("\n");
    	
    	if ( (in = fopen(inputName, "r")) == NULL) {
    		printf("Can't open %s for reading.\n", inputName);
    		return 1;
            }
    	
    	do {
    		for (i = 0; i < 20; ++i) {
    			fgets(linebuf, 20, in);
    			printf("%s", linebuf);
    		} 
    		
    		printf("Enter a character (q to quit): ");
    		scanf("%c", &command);
    		getchar();
    		
    	} while (command != 'q');
    	
    	
    	return 0;
    }
    The code after following both scanf calls with getchar();

    Code:
    //This one fails to quit when 'q' is entered after a few cycles
    
    #include <stdio.h>
    
    int main (void)
    {
    	char linebuf[200], inputName[64];
    	FILE *in;
    	char command = 'a';
    	int i;
    	
    	printf("Enter name of file to be copied: ");
    	scanf("%63s", inputName);
            getchar();
    	printf("\n");
    	
    	if ( (in = fopen(inputName, "r")) == NULL) {
    		printf("Can't open %s for reading.\n", inputName);
    		return 1;
            }
    	
    	do {
    		for (i = 0; i < 20; ++i) {
    			fgets(linebuf, 20, in);
    			printf("%s", linebuf);
    		} 
    		
    		printf("Enter a character (q to quit): ");
    		scanf("%c", &command);
    		getchar();
    		
    	} while (command != 'q');
    	
    	
    	return 0;
    }
    Code:
    /*This one seems to loop through two or three times, prompt the user for
     * input and simply prompt the user again, but it does quit when 'q' is entered. */
    
    #include <stdio.h>
    
    int main (void)
    {
    	char linebuf[200], inputName[64];
    	FILE *in;
    	char command = 'a';
    	int i = 0;
    	
    	printf("Enter name of file to be copied: ");
    	scanf("%63s", inputName);
    	getchar();
    	printf("\n");
    	
    	if ( (in = fopen(inputName, "r")) == NULL) {
    		printf("Can't open %s for reading.\n", inputName);
    		return 1;
            }
    	
    	do {
    		while (i < 20 && fgets(linebuf, 20, in) != NULL)
    			printf("%s", linebuf);
    		
    		printf("Enter a character (q to quit): ");
    		scanf("%c", &command);
    		getchar();
    		
    	} while (command != 'q');
    	
    	
    	return 0;
    }
    I know this is really elementary stuff, so I'm sorry to trouble people with it. I appreciate your help immensely!

  15. #15
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    Note that here:
    Code:
    while (i < 20 && fgets(linebuf, 20, in) != NULL)
        printf("%s", linebuf);
    the first part of the conditional will never be false, as you're never changing the value of i.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Output Stars With for loop
    By Magic-Man-fci in forum C++ Programming
    Replies: 6
    Last Post: 12-27-2010, 04:43 AM
  2. Add a Loop to print the output?
    By big-tony in forum C Programming
    Replies: 23
    Last Post: 05-22-2009, 10:38 AM
  3. While Loop does not have an output
    By pannet1 in forum C++ Programming
    Replies: 2
    Last Post: 05-25-2005, 11:09 AM
  4. Need help : eof, loop, output file
    By henz321 in forum C++ Programming
    Replies: 5
    Last Post: 05-05-2005, 06:54 PM
  5. Loop output is not quite what I want
    By Zalbik in forum C++ Programming
    Replies: 17
    Last Post: 10-31-2002, 12:35 PM