C Board  

Go Back   C Board > General Programming Boards > C Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 11-19-2008, 01:54 AM   #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!
dnguyen1022 is offline   Reply With Quote
Old 11-19-2008, 02:22 AM   #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.
__________________
Do you know why bbebfe is NOT bbebfe?

Last edited by bbebfe; 11-19-2008 at 02:26 AM.
bbebfe is offline   Reply With Quote
Old 11-19-2008, 02:54 PM   #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.
dnguyen1022 is offline   Reply With Quote
Old 11-19-2008, 03:01 PM   #4
Registered User
 
Join Date: Sep 2008
Posts: 46
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;
}
blurx is offline   Reply With Quote
Old 11-19-2008, 03:06 PM   #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?
dnguyen1022 is offline   Reply With Quote
Old 11-19-2008, 03:16 PM   #6
and the hat of Jobseeking
 
Salem's Avatar
 
Join Date: Aug 2001
Location: The edge of the known universe
Posts: 21,680
> 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.

Salem is offline   Reply With Quote
Old 11-19-2008, 04:33 PM   #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?
dnguyen1022 is offline   Reply With Quote
Old 11-20-2008, 12:04 AM   #8
and the hat of Jobseeking
 
Salem's Avatar
 
Join Date: Aug 2001
Location: The edge of the known universe
Posts: 21,680
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.

Salem is offline   Reply With Quote
Old 11-20-2008, 07:14 PM   #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?
dnguyen1022 is offline   Reply With Quote
Old 11-21-2008, 12:42 AM   #10
C++ Witch
 
laserlight's Avatar
 
Join Date: Oct 2003
Location: Singapore
Posts: 11,338
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>.
__________________
C + C++ Compiler: MinGW port of GCC
Build + Version Control System: SCons + Bazaar

Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
laserlight is offline   Reply With Quote
Old 11-21-2008, 12:43 AM   #11
CSharpener
 
vart's Avatar
 
Join Date: Oct 2006
Posts: 5,324
line[MAXLINE]
this is out of bounds access, the valid indexes are from 0 to MAXLINE - 1
__________________
If I have eight hours for cutting wood, I spend six sharpening my axe.
vart is offline   Reply With Quote
Old 11-21-2008, 03:03 PM   #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.
dnguyen1022 is offline   Reply With Quote
Old 11-26-2008, 12:48 PM   #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:%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;
}
dnguyen1022 is offline   Reply With Quote
Old 11-26-2008, 01:20 PM   #14
and the Hat of Guessing
 
tabstop's Avatar
 
Join Date: Nov 2007
Posts: 8,825
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?
tabstop is online now   Reply With Quote
Old 11-26-2008, 02:15 PM   #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.
dnguyen1022 is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump


All times are GMT -6. The time now is 09:44 PM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22