Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

very puzzled; compiles but nothing happens

Status
Not open for further replies.

jjohnn

Technical User
Feb 11, 2003
43
US
I'm working through K&R C Programming Language, and wrote a program to remove comments from a C program. The other exercises from the book have been challenging, but I've done them all so far.

I compile it with no complaints, and run it, but my shell comes back with no visible sign of anything. (I am on NT working from the command line with gcc). I add
Code:
printf("in main");
, and then get complaints that my variables (appearing right below my printf) are not initialized. Without the printf, the compiler is silent. I am compling the right program; the variables it mentions when I have the printf statement are right. Here's the program.
Code:
/*remcoms.c*
 * removes c comments from a program
 */

#include <stdio.h>

#define BUFFSIZE 1000

int getline(char line[], int maxline);
int endcomm(char s[], int ind);
int startcomm(char s[], int ind);


int main(){

	char line [BUFFSIZE]; /*holds input line*/
	int incomment =0; /* true within a comment*/
	int len;
	int i;

	while ( (len=getline(line, BUFFSIZE) ) ){
			while(i<len){
				
			/* echo input until the start of a comment*/
				while (!startcomm(line, i) && incomment ==0){
					putchar(line[i]);
					i++;
				}

			/* stop echoing input when a comment is reached */
				if(startcomm(line, i)){
					incomment = 1;
					while( !endcomm(line,i) )
						/*move past the comment*/
						i++;
				}

			/* when we reach the end of a comment, we need to 
			 * move past the two characters '*' and '\' */
				if (endcomm(line, i) ){
					i++;
					i++;
					incomment =0;
			}
		}
	}
	return 0;
}

/* 
 * K&R fxn, retrieves a line of input 
 * into the char array s, and returns 
 * the length of the line
 */

int getline(char s[], int lim){
	int c,i;
	
	for(i=0; i< lim-1 &&(c = getchar())!= EOF && c !='\n'; ++i)
		s[i] = c;
	if( c== '\n'){
		s[i] = c;
		++i;
	}	
	s[i] = '\0';
	return i;
}

int startcomm(char s[], int ind){
		return (s[ind] == '/' && s[ind+1] =='*');
}

int endcomm(char s[], int ind){
		return (s[ind] == '*' && s[ind +1] == '/');
}
 
The reason you get the error is probably because of a rule in C that requires you to declare all variables at the top of a block, and before any executable statements (such as printf). Otherwise, you get errors like the one you got. It's a sorta arbitrary rule, IMHO, and it can be annoying, but you have to follow it... at least until compilers support the pretty newly-restandardized C, which drops this limitation.

As for the program not having any effect, it looks like you want to feed the file to be stripped of comments into this program's standard input. Use the usual shell input redirection operator. For example:

$ comment_stripper.exe < file_to_be_stripped.c
 
Thanks, that helps.

The other exercises in the book all took input from stdin, and this one was to act similarly. The getline() method is using getchar() to presumably wait for user input and feed it to the string (until \n or BUFSIZE is reached).

My other uses of this subroutine had exactly that functionality. Redirecting input is certainly more of realworld functionality, but I'm unsure why this program won't wait for input from stdin.

Is there an obvious thing I am not seeing?
 
I didn't initialize &quot;i&quot; at top of the program.

I have other problems, (an infinite loop) but at least I am getting output now. Thanks for the help.
 
You are incrementing &quot;i&quot; twice.

if (endcomm(line, i) ){
i++;
i++;
incomment =0;

And again here (according to my study buddy)

int getline(char s[], int lim){
int c,i;

for(i=0; i< lim-1 &&(c = getchar())!= EOF && c !='\n'; ++i) /*HERE*/
s = c;
if( c== '\n'){
s = c;
++i; /* and HERE*/
}
s = '\0';
return i;
}
 
Thanks, tbushmaker.

My understanding of scoping is that the &quot;i&quot; inside the subroutine getline() will not clash with the &quot;i&quot; in main().
Am I misunderstanding you to say that they do clash, or do I misunderstand teh scoping rules?

Appreciate the help,
John
 
Maybe I am seeing ddoouubbllee.

I don't code regularly. It never does what I want it to.

The subroutine has i++; i++; in the first if loop (if(endcomm.

In the getline subroutine lim is not set.
Then i is always less than lim-1.

Study buddy unavailable, probably feeding her kids, but

MY OPINION: The for loop never ends.
 
Yes, the i in main() does NOT conflict with the i in getline(). They are separate and distinct and cannot be seen from outside their respective routine.

 
Got it to work. Thanks for your help, everyone.
Code:
/*removecoms.c
 * K&R exercise from first chapter*
 * removes c comments from a program
 */

#include <stdio.h>

#define BUFFSIZE 1000

int getline(char line[], int maxline);
int endcomm(char s[], int ind, int len);
int startcomm(char s[], int ind, int len);


int main(){
	char line [BUFFSIZE]; /*holds input line*/
	int incomment =0; /* true within a comment*/
	int len; /*lenght of input string*/
	int i=0;
	
	while ( (len = getline(line, BUFFSIZE) ) ){
		while(i<len){

		/* echo input until the start of a comment*/
			while (!startcomm(line, i, len) && incomment ==0){
				putchar(line[i]);
				i++;
			}
		/* stop echoing input while in a comment */
			if(startcomm(line, i, len) || incomment==1){
				incomment = 1;
				while( !endcomm(line,i, len) && i<len){
					i++;/*move past the comment*/
				}
		 /* once out of the comment, reset the flag and
		  * move past the two characters '*' and '\' */
				if(endcomm(line, i, len)){
					incomment=0;
					i=i+2;
				}
			}
		}
		i=0; /*reset for beginning of next line*/
	}
	return 0;
}

/* 
 * K&R fxn, retrieves a line of input 
 * into the char array s, and returns 
 * the length of the line
 */

int getline(char s[], int lim){
	int c,i;
	
	for(i=0; i< lim-1 &&(c = getchar())!= EOF && c !='\n'; ++i)
		s[i] = c;
	if( c== '\n'){
		s[i] = c;
		++i;
	}	
	s[i] = '\0';
	return i;
}

/*determines if a comment has started*/
int startcomm(char s[], int ind, int len){
	if (ind < len-1)
		return (s[ind] == '/' && s[ind+1] =='*');
	else return 1;
}

/*determines if a comment has ended*/
int endcomm(char s[], int i, int len){
	if(s[i] =='\n' || s[i]=='\0')
		return 0;
	else if (i<len-1) 
		return (s[i] == '*' && s[i+1] == '/');
}
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top