Thread: Printing Length of Input and the Limited Input

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

    Printing Length of Input and the Limited Input

    Hello all! First post here! I look forward to receiving your generous help so eventually I will be decent enough to help others. Anyways..straight to the point...

    So I am learning to program in C using the K&R book. I am struggling with a problem, in the book. For those with the book, chapter 1.9, exercise 1-16.
    For those without the book; The book has given me a piece of code that has the main function and two other functions. The original code simply took in an input of lines, and printed out the longest line as allowed by the MAXLINE number. The exercise now wants me to modify only the MAIN code so that it prints out the actual length of the longest line, and as much as possible of the line as limited by MAXLINE.

    The way I attempted to do it does not even pass the most simple test, in which I only give it one line. It skips the first character and prints out the rest that is possible according to the limit, but it also returns back a length of 0, which is not valid. Can somebody help me please?

    This is the original code from the book...

    Code:
    #include <stdio.h>
    #define MAXLINE 1000
    
    int getLine(char line[], int maxline);
    void copy(char to[], char from[]);
    
    //prints longest input line
    main(){
    	int len; //current line length
    	int max; //maximum length seen so far
    	char line[MAXLINE]; //current input line
    	char longest[MAXLINE]; //longest line saved here
    
                    max = 0;
    
    	while ((len = getline(line, MAXLINE)) > 0)
    		if (len > max){
    			max = len;
    			copy(longest, line);
    		}
    		if (max > 0){ //there was a line
    			putchar('\n');
    			printf("%s", longest);
    		}
    		return 0;
    }
    
    //read a line into s, return length
    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;
    }
    
    //copy from into to: assume to is big enough
    void copy(char to[], char from[]){
    	int i;
    
    	i = 0;
    	while ((to[i] = from[i]) != '\0')
    		++i;
    }

    Here is my modified version...

    Code:
    #include <stdio.h>
    #define MAXLINE 10
    
    int getline(char line[], int maxline);
    void copy(char to[], char from[]);
    
    //prints longest input line
    main(){
    	int c; //the char
    	int len; //current line length
    	int max; //maximum length seen so far
    	int maxlen; //longest line
    	int possiblemax; //possibly max line
    	char line[MAXLINE]; //current input line
    	char longest[MAXLINE]; //longest line saved here
    	
    	//sets default values
    	max = maxlen = possiblemax = 0;
    
    	//while loop for checking end of input
    	while ((c = getchar()) != EOF){
    		
    		//if case for when the char is equal to a new line
    		if (c == '\n'){
    
    			//when char is equal to a new line
    			//and possiblemax is greater than maxlen
    			//change maxlen to equal to possible max
    			//reset possible max to 0
    			if (possiblemax > maxlen){
    				maxlen = possiblemax;
    				possiblemax = 0;
    			}
    
    			//else just set possiblemax back to 0
    			else possiblemax = 0;
    		}
    
    		//if not a new line, add 1 to possiblemax
    		else ++possiblemax;
    
    	while ((len = getline(line, MAXLINE)) > 0)
    		if (len > max){
    			max = len;
    			copy(longest, line);
    		}
    		if (max > 0){ //there was a line
    			//prints maxlen value
    			printf("length:%d", maxlen);
    			putchar('\n');
    			printf("%s", longest);
    		}
    		return 0;
    	}
    }
    
    //read a line into s, return length
    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;
    }
    
    //copy from into to: assume to is big enough
    void copy(char to[], char from[]){
    	int i;
    
    	i = 0;
    	while ((to[i] = from[i]) != '\0')
    		++i;
    }
    Thank you for your future help!

  2. #2
    Why bbebfe is not bbebfe? bbebfe's Avatar
    Join Date
    Nov 2008
    Location
    Earth
    Posts
    27
    [I have not run your code]
    You have two while loops and of which are both get character from stdin. the outer loop eats the first character the user inputted each time.

    You put the return statement within the outer loop, I think it's the reason your program stops after giving it only one line.
    Last edited by bbebfe; 11-19-2008 at 02:26 AM.
    Do you know why bbebfe is NOT bbebfe?

  3. #3
    Registered User
    Join Date
    Nov 2008
    Posts
    110
    Code:
    #include <stdio.h>
    #define MAXLINE 10
    
    int getline(char line[], int maxline);
    void copy(char to[], char from[]);
    
    //prints longest input line
    main(){
    	int c; //the char
    	int len; //current line length
    	int max; //maximum length seen so far
    	int maxlen; //longest line
    	int possiblemax; //possibly max line
    	char line[MAXLINE]; //current input line
    	char longest[MAXLINE]; //longest line saved here
    	
    	//sets default values
    	max = maxlen = possiblemax = 0;
    
    	//while loop for checking end of input
    	while ((c = getchar()) != EOF){
    		
    		//if case for when the char is equal to a new line
    		if (c == '\n'){
    
    			//when char is equal to a new line
    			//and possiblemax is greater than maxlen
    			//change maxlen to equal to possible max
    			//reset possible max to 0
    			if (possiblemax > maxlen){
    				maxlen = possiblemax;
    				possiblemax = 0;
    			}
    
    			//else just set possiblemax back to 0
    			else possiblemax = 0;
    		}
    
    		//if not a new line, add 1 to possiblemax
    		else ++possiblemax;
    
    	while ((len = getline(line, MAXLINE)) > 0)
    		if (len > max){
    			max = len;
    			copy(longest, line);
    		}
    		if (max > 0){ //there was a line
    			//prints maxlen value
    			printf("length:%d", maxlen);
    			putchar('\n');
    			printf("%s", longest);
    		}
    	}
    
    		return 0;
    }
    
    //read a line into s, return length
    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;
    }
    
    //copy from into to: assume to is big enough
    void copy(char to[], char from[]){
    	int i;
    
    	i = 0;
    	while ((to[i] = from[i]) != '\0')
    		++i;
    }
    So I modified my code so the return 0 would be outside the while loop now. However, what can I do to prevent my first letter from being "eaten"? I am stumped on that part..Also my length likes to return a length of 0, despite it knowing what the longest line is. To me it seems like my length finding function seems correct though. I also noticed it only eats the first letter of the first line, and this can only been seen when the first line is the longest line.

  4. #4
    Registered User
    Join Date
    Sep 2008
    Posts
    58
    In your getline function, your for loop is missing brackets after it.

    Code:
    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;
    }

  5. #5
    Registered User
    Join Date
    Nov 2008
    Posts
    110
    That is exactly the way the K&R book gave it to me...possible typo? Or maybe the authors have their own reason for doing that?

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    > In your getline function, your for loop is missing brackets after it.
    No it isn't.
    The single-line for loop does all the work.

    > However, what can I do to prevent my first letter from being "eaten"?
    Why do you even need the first while loop?
    The
    while ((len = getline(line, MAXLINE)) > 0)
    does the right thing with EOF anyway.
    Your attempt to detect an early EOF is just messing things up.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Nov 2008
    Posts
    110
    Hmm..I understand what you mean...but now how would I go about finding the length of the line without being limited by the number passed into the getline function?

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    In the code which calls getline(), detect whether the returned line contains a \n (or not) to decide whether the line is really long.

    Unless you want to make getline a lot more complicated with calls to malloc and realloc, to expand the space as the user keeps typing.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Registered User
    Join Date
    Nov 2008
    Posts
    110
    I think I understand what you are saying. However is it possible to change the array so that its able to fit new characters? Would I have to make a new array for the purpose of "overmax" lines or can I change the array size? Also would I add something that is similar to

    Code:
    if (line[MAXLINE] != '\n'){
    
    ?expand the array?
    }
    within the main function?

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    Quote Originally Posted by dnguyen1022
    However is it possible to change the array so that its able to fit new characters? Would I have to make a new array for the purpose of "overmax" lines or can I change the array size?
    Instead of your current fixed size arrays, you would use dynamic memory allocation, e.g., with malloc(), realloc() and free() from <stdlib.h>.
    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
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    line[MAXLINE]
    this is out of bounds access, the valid indexes are from 0 to MAXLINE - 1
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  12. #12
    Registered User
    Join Date
    Nov 2008
    Posts
    110
    Hmm...alright I'll change it around and see what I get, with the MAXLINE - 1 in mind. Also
    silverlight, I apologize if this sounds rude, but I am trying to follow the book and using the information that they have given me so far to solve this problem. I believe I should solve this problem with the basics before getting into more complicated stuff or by using shortcuts. I appreciate your help and still want your help to solve this problem but in a less advanced way...for now.

  13. #13
    Registered User
    Join Date
    Nov 2008
    Posts
    110
    So..I tried it again...this time my code does not seem to be doing anything. I think I have the concept down. However my code is wrong....I think the
    Code:
    (c = getchar())
    must be intefering with my getline function...can somebody help me please?

    Code:
    #include <stdio.h>
    #define MAXLINE 10
    
    int getLine(char line[], int maxline);
    void copy(char to[], char from[]);
    
    //prints longest input line
    main(){
    	int len; //current line length
    	int max; //maximum length seen so far
    	int possiblemax; //possible maximum length
    	int realmax; //the real maximum length
    	int c; //the char
        char line[MAXLINE]; //current input line
    	char longest[MAXLINE]; //longest line saved here
    	
        max = possiblemax = realmax = 0;
    
    	while ((len = getline(line, MAXLINE)) > 0)
    		//checks to see if array ends with a new line
    		if (line[len - 1] != '\n'){
    
    			//while c is not end of file
    			while ((c = getchar()) != EOF){
    				//if c is not equal to a new line
    				if (c != '\n'){
    					//while c is not a new line add one to possible max
    					while(c != '\n'){
    						     ++possiblemax;
    							 }
    				}
    
    				//else if is equal to a new line
    				else if (c == '\n'){
    					//if possiblemax is greater than real max
    					//set realmax to possiblemax
    					//reset possible max
    					if (possiblemax > realmax){
                                    realmax = possiblemax;
                                    possiblemax = 0;
                    }
    
    				//otherwise reset possiblemax
    					else possiblemax = 0;
                    }
                }
            }
                                                
    		if (len > max){
    			max = len;
    			copy(longest, line);
    		}
    
    		if (max > 0){ //there was a line
    			printf("length:&#37;d", realmax);
    			putchar('\n');
    			printf("%s", longest);
    		}
    		return 0;
    }
    
    //read a line into s, return length
    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;
    }
    
    //copy from into to: assume to is big enough
    void copy(char to[], char from[]){
    	int i;
    
    	i = 0;
    	while ((to[i] = from[i]) != '\0')
    		++i;
    }

  14. #14
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Code:
    while(c != '\n'){
    	++possiblemax;
    }
    Good luck getting that loop to stop. That's assuming you decide on the name of the function getL/line, since your program doesn't compile as is. And is the point of this c thing in main to throw away the rest of the line?

  15. #15
    Registered User
    Join Date
    Nov 2008
    Posts
    110
    Wouldn't it stop when it gets to a new line or when it reaches EOF due to the while loop that it is in? Also it is suppose to get the length of the REST of the line..since the getline stops whenever it reaches its MAXLINE limit. The main purpose of the program is to print out the length of the longest line, and print out as much as possible of the line as limited by MAXLINE.

Popular pages Recent additions subscribe to a feed