Thread: fgets and breaking out of while loop

  1. #1
    Registered User
    Join Date
    Nov 2008
    Posts
    83

    fgets and breaking out of while loop

    I'm trying to create a file reader for files with the following basic structure:

    a INFOA2
    b INFOB1
    b INFOB2
    c INFOC1
    c INFOC2
    a INFOA2

    Here is what I have so far

    Code:
    while ((fgets(this, 99, fp)) != NULL)
    {
         if (this[0] == 'a')
         {
              // DO THIS
    
              while ((fgets(this, 99, fp)) != NULL)
              {
                    if (this[0] == 'b');
                    else if (this[0] == 'c');
              }
         }
    }
    The problem is that in the inner for loop, if "this" is not 'b' or 'c', it should break out of loop and go to look for next 'a'. But with the current if and else if statements, it will of course just skip the next 'a' and go to the next 'b' or 'c'. How can I break out of this loop?
    Probably an else statement, but what should it include? I tried an empty else...
    Thanks

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Why wouldn't it include "break"?

    Of course the trick is that you've already read the line, and you don't want to read it again. You should use ... well, I don't know if it has a real name, but when I was learning COBOL (shudder) it was called control-break programming (shudder) -- you read each line in one loop without trying to nest things.

  3. #3
    Registered User
    Join Date
    Nov 2008
    Posts
    83
    break! right on. thanks

  4. #4
    Registered User
    Join Date
    Nov 2008
    Posts
    83
    Hmm, I'm still having a looping issue:

    Code:
    while ((fgets(this, 99, fp)) != NULL)
    {
         if (this[0] == 'a')
         {
              // DO THIS
    
              while ((fgets(this, 99, fp)) != NULL)
              {
                    if (this[0] == 'b')
                       // DO THAT
                    else if (this[0] == 'c')
                       // DO OTHER
                    else
                       break;
              }
         }
    }
    The problem is this:
    If the file I am reading has
    a INFOA1
    b INFOB1
    b INFOB2
    c INFOC1
    c INFOC2
    a INFOA2

    Then, when I run the program, I will enter inner loop after encountering first line starting with 'a'. I will then access both 'b' s, but since 'c' is an else if, I never seem to reach them.

    The problem is my loop structure. Does anyone see what I'm saying and know a way to fix?
    Thank you for your help.

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    If the code you have posted is REALLY what you are working on (rather than some extremely simplified version), it should work fine with the else if to get to the 'c' type lines.

    You may need to post more realistic code if the posted code isn't EXACTLY like your real code.

    --
    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.

  6. #6
    Registered User
    Join Date
    Nov 2008
    Posts
    83
    Sorry, it is actually more like:

    Code:
    while ((fgets(this, 99, fp)) != NULL)
    {
         if (this[0] == 'a')
         {
              // DO THIS
    
              while ((fgets(this, 99, fp)) != NULL)
              {
                    if (this[0] == 'b')
                       sscanf(this, "b %i", &variable);
                    else if (this[0] == 'c')
                       sscanf(this, "c %i", &variable1);
                    else
                       break;
              }
         }
    }

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    That should work.

    --
    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.

  8. #8
    Registered User
    Join Date
    Nov 2008
    Posts
    83
    if I have:

    else
    break;

    It never gets to the 'c' lines but does get to every 'a' and 'b'
    If I replace that else with:
    else if (this[0] == 'a')
    break;
    Then it does get to the 'c' lines, but never reaches the second 'a'

  9. #9
    Registered User
    Join Date
    Nov 2008
    Posts
    83
    Any idea?

  10. #10
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Ah, hang on a bit. You read a line, then you read another line. Then you read a line with 'a' at the beginning in the inner loop, then break. You are then reading another line in the outer loop before you look at the first letter of the string - and in your posted input file, it actually would then be finished because the second 'a' line is the last one in the file.

    --
    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.

  11. #11
    Registered User
    Join Date
    Nov 2008
    Posts
    83
    Oops,
    sorry again.

    Should be like:
    a INFOA1
    b INFOB1
    b INFOB2
    c INFOC1
    c INFOC2
    a INFOA2
    b INFOB3
    b INFOB4
    c INFOC3
    c INFOC4

  12. #12
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I modified your code a bit:
    Code:
    #include <stdio.h>
    
    int main()
    {
    	FILE *fp = fopen("test.txt", "r");
    	char line[99];
    	char variable[99];
    	char variable1[99];
    	if (!fp)
    	{
    		fprintf(stderr, "Could not open test.txt\n");
    		return 1;
    	}
    
    	while ((fgets(line, 99, fp)) != NULL)
    	{
    		printf("Outer Line =%s\n", line);
    		if (line[0] == 'a')
    		{
    			while ((fgets(line, 99, fp)) != NULL)
    			{
    				printf("Inner Line =%s\n", line);
    				if (line[0] == 'b')
    					sscanf(line, "b %s", variable);
    				else if (line[0] == 'c')
    					sscanf(line, "c %s", variable1);
    				else
    					break;
    			}
    			printf("var = %s, var1 = %s\n", variable, variable1);
    		}
    	}
    	return 0;
    }
    And I got this output, which quite clearly shows that you are skipping over the second 'a' line:
    Code:
    Outer Line =a INFOA1
    
    Inner Line =b INFOB1
    
    Inner Line =b INFOB2
    
    Inner Line =c INFOC1
    
    Inner Line =c INFOC2
    
    Inner Line =a INFOA2
    
    var = INFOB2, var1 = INFOC2
    Outer Line =b INFOB3
    
    Outer Line =b INFOB4
    
    Outer Line =c INFOC3
    
    Outer Line =c INFOC4
    This was done as a quick hack - it's not intended as "how you go about writing good programs".

    --
    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.

  13. #13
    Registered User
    Join Date
    Nov 2008
    Posts
    83
    So, how do I work around this? Should I take you to mean that even your modification produced the same result? What might be a better way to accomplish this?

  14. #14
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    My modification is to show you what happens.

    Why do you feel that you need two loops in the first place?

    I personally would be very tempted to just put a switch-statement with case 'a', case 'b' and case 'c' in the outer loop, and completely remove the inner loop. But I suspect that although you say this is what your input and your actual code is, that it's still not actual code and actual input (particularly as your input is not integer values, but you are reading with %i).
    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.

  15. #15
    Registered User
    Join Date
    Nov 2008
    Posts
    83
    How do I format a switch of (line[0] == 'a')
    Thanks for all your help!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Breaking out of the loop
    By ICool in forum C Programming
    Replies: 5
    Last Post: 09-24-2007, 08:27 AM
  2. Replies: 12
    Last Post: 10-17-2005, 06:49 AM
  3. breaking out of program
    By sworc66 in forum C Programming
    Replies: 4
    Last Post: 11-02-2003, 12:38 AM