Thread: Infinite Loop

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

    Infinite Loop

    Can someone please examine my code here. The program is supposed to remove all comments from a C program. So far it only checks for // comments. I'm feeding it it's own source as the input. For some reason it doesn't work however. When I run the program cygwin just gets stuck in an infinite loop (at least I think). Could someone please tell me what the problem is?
    Code:
    #include <stdio.h>
    #define MAXLENGTH 1000
    
    int Getline(char str[]);
    
    int main(void) {
    	char line[MAXLENGTH];
    	while(Getline(line) != 0) 
    		printf("%s\n", line);
    	return 0;
    }
    
    int Getline(char str[]) {
    	int i;
    
    	int c;
    	int linestart;	// linestart = index of start of // comment, linecomment = boolean of whether the previous character was a /
    	int linecomment;
    	for(i = 0; ((c = getchar()) != '\n') && (i < MAXLENGTH); i++) {
    		linecomment = 0;
    		if(i == EOF)
    			return 0;
    		if(c == '/')
    			linecomment = 1;
    		else if(linecomment && c == '/'){
    			str[i-1] = '\0';
    			return 0;
    		}
    		str[i] = c;
    	}
    	return i;
    }

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I do not think that assigning 0 to linecomment on every iteration is correct since you use linecomment to record the fact that a '/' was encountered in the previous iteration. When making this change, you need to set linecomment to 0 when you encounter a character other than '/', otherwise a sequence like "/a/" would be treated as a comment.

    I suspect that it may be easier to process the file at once character by character, ignoring characters when you are in a comment state. Also, note that you probably want to compare c, not i, to EOF.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Aug 2011
    Posts
    10
    asjkl;djkfhidshagisdg screw me. Stupid typo, I guess the comparison of i to EOF when I meant to compare C is what caused the infinite loop. As for the linecomment thing, that's what I'm doing... it's setting it to 0 when it encounters a character other than a '/'. However I'll move it to the end of the loop.

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by ASCII
    As for the linecomment thing, that's what I'm doing... it's setting it to 0 when it encounters a character other than a '/'. However I'll move it to the end of the loop.
    At the moment, it is setting linecomment to 0 regardless of what the previous character was. Moving it to the end of the loop will not make a difference. What will make a difference is making this assignment be controlled by an if statement (whether in the if or else part).
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Ok ... a couple of suggestions...

    First I would not try to parse this character by character... line by line makes more sense... You can use strstr() to get a pointer to the // marker and insert a newline ( \n ) and a null (\0) at that point deleting the rest of the line.

    Second I would not combine everything into one function... if you're going to do that, just put it all in Main. Instead I would have my main function martialling the other functions, a function to load the line, a function to turf the comments that is only called for lines longer than 3 characters (// + newline) and still another to write the line to a file...

    Hint: Smaller blobs usualy work best.

    Look into functions like fgets(), fputs(), strstr() and strcpy() to do most of the work for you...
    Last edited by CommonTater; 09-02-2011 at 04:22 PM.

  6. #6
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by CommonTater View Post
    You can use strstr() to get a pointer to the // marker and insert a newline ( \n ) and a null (\0) at that point deleting the rest of the line.
    Code:
    printf( "Comments on a single line start with //\n" ); // tell how to use a line comment

    Quzah.
    Hope is the first step on the road to disappointment.

  7. #7
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by quzah View Post
    Code:
    printf( "Comments on a single line start with //\n" ); // tell how to use a line comment
    Quzah.
    Picky picky picky! But also correct...

    In my own defense... what I was doing is called "Pointing in the right direction"....

  8. #8
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    There are lots of things that make this non-trivial:
    1. Comment characters can appear inside strings.
    Code:
    printf("//I am not a comment!");
    2. Strings themselves can contain \" making their end harder to detect than you might think.
    Code:
    printf("Well, \"I am not // a comment either\"");
    3. /*/ can be either the start or the end of a comment block.
    Code:
    Add or remove the first slash on the next line and change an addition into a multiply.
    //*
    a = b + c;
    /*/
    a = b * c;
    // */
    4. Removing /* */ style comments can screw up code that uses them as the only separator between two other symbols. In fact you won't even necesarily get a compile error. Contrived example
    Code:
    #define a 1
    #define b +2
    #define ab 12
    int x = a/*careful taking me out!*/b;
    Bottom line, doing this completely correctly requires a basic parser, not just a search and replace mechanism. It doesn't need to be as complex as a C compiler though.

    The real question though is, why would you write such a thing? Surely comments are an asset?
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  9. #9
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by iMalc View Post
    The real question though is, why would you write such a thing? Surely comments are an asset?
    A. Because it's an assignment.
    B. For the experience of doing it.


    Quzah.
    Hope is the first step on the road to disappointment.

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by CommonTater
    First I would not try to parse this character by character... line by line makes more sense...
    I suggest processing character by character because that is what ASCII is already doing, except that the characters in each line are processed as a batch, which seems like an unnecessary complication. Reading in line by line and processing character by character would make sense, but then line continuations (a backslash used to join the next line to the current line) might be a little more tricky to deal with.

    Quote Originally Posted by iMalc
    3. /*/ can be either the start or the end of a comment block.
    It looks like ASCII is heading towards the idea of using states to determine what to do next, so I doubt this one would be a problem. #1 and #2 would be a matter of getting the string state processing correct, and #4 is a matter of replacing each comment with a space, which is required of compilers by the C standard anyway.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #11
    Registered User
    Join Date
    May 2011
    Location
    Around 8.3 light-minutes from the Sun
    Posts
    1,949
    Quote Originally Posted by ASCII View Post
    Can someone please examine my code here. The program is supposed to remove all comments from a C program. So far it only checks for // comments. I'm feeding it it's own source as the input. For some reason it doesn't work however. When I run the program cygwin just gets stuck in an infinite loop (at least I think). Could someone please tell me what the problem is?
    Quote Originally Posted by iMalc View Post
    Bottom line, doing this completely correctly requires a basic parser, not just a search and replace mechanism. It doesn't need to be as complex as a C compiler though.
    iMalc hit the head of the nail on this one, in order to implement this you are going to want to look into making a simple iterative or recursive parser for handling the input. You are going to want to define your delimeters for your comments, and then process the input based on those delimeters. Char by char processing is the way to go with this, however I would use a switch statement for your delimeters and then set your machine state accordingly. Usually one would use an intermediate buffer such as a stack implementation prior to sending your parsed input to the final output stream.
    Quote Originally Posted by anduril462 View Post
    Now, please, for the love of all things good and holy, think about what you're doing! Don't just run around willy-nilly, coding like a drunk two-year-old....
    Quote Originally Posted by quzah View Post
    ..... Just don't be surprised when I say you aren't using standard C anymore, and as such,are off in your own little universe that I will completely disregard.
    Warning: Some or all of my posted code may be non-standard and as such should not be used and in no case looked at.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. infinite loop
    By ssjnamek in forum C++ Programming
    Replies: 11
    Last Post: 09-25-2005, 05:08 PM
  2. stays in loop, but it's not an infinite loop (C++)
    By Berticus in forum C++ Programming
    Replies: 8
    Last Post: 07-19-2005, 11:17 AM
  3. infinite loop
    By puckparches in forum C++ Programming
    Replies: 4
    Last Post: 05-18-2005, 10:12 PM
  4. infinite loop
    By puckparches in forum C Programming
    Replies: 2
    Last Post: 05-18-2005, 03:10 PM
  5. infinite loop
    By bruce in forum C++ Programming
    Replies: 1
    Last Post: 11-03-2002, 04:35 PM