#1
  1. No Profile Picture
    .
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2002
    Posts
    296
    Rep Power
    13

    stuck on another k&r exercise


    i'm stuck on one of the exercises from the k&r book:

    write a program to 'fold' long input lines into two or more shorter lines after the last non-blank character that occurs before the n-th colum of input.

    this is what i've got so far. i've tried various things all of which haven't worked in different ways :( (ignore anything to do with tabs - haven't dealt with those yet):

    Code:
    #include <stdio.h>
    #define LINELEN	10		/* the required length of each line (splitline[]) */
    #define TABSTOP	5		/* width of the tab stop columns */
    #define MAXLINE 	1024	/* maximum line length */
    
    main()
    {
    	int getline(char line[], int limit);
    
    	char line[MAXLINE];
    	char splitline[MAXLINE];
    	int i, k;
    	int j=0;
    	int gap;				/* to track the last space or tab pos */
    	int col=0;				/* to track the column number (which can be different to
    						the variable i because of tabs: 1char = several cols) */
    	int linelen=LINELEN;
    
    	while(getline(line, MAXLINE) > 0) {			/* while there's another full line */
    		for (i=0; line[i] != '\0'; i++) {
    			if (col>=linelen || line[i]=='\n') {		/* print short line */
    				if (gap==0)				/* no gaps cover */
    					gap=col++;
    				splitline[gap++]='\n';
    				splitline[gap]='\0';
    				printf("%s", splitline);
    				i-=col-gap;				/* jump back to where last gap is */
    				gap=col=j=0;
    			}
    			if (line[i]=='\t') {		
    				;	/* tabstuff */
    			} else {
    				if (line[i]==' ')
    					gap=col;
    				splitline[j++]=line[i];
    			}
    			col++;
    		}
    	}
    }
    
    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;
    }
    the problem is, i think, with a conflict of, added \n's to get the shortend lines, and the final \n that is on the end of the line that is typed. what's the best way to deal with this. i've tried several ways i just can't get it to work :/ very annoying. and i get a segmentation fault error when the very first bit of input goes over the specified LINELENgth value and has no spaces in.

    this is with the LINELEN set to 10:
    Code:
    the first line of input is ok apart from mentioned segmentation fault
    the first
    line of
    input is
    ok apart
    from
    mentioned
    segmentati
    on
    fault
    but the second line gets annoying extra \n at start
    
    but the
    second
    line gets
    annoying
    extra \n
    at
    start
    oh also another problem with it - the last word of the input, 'fault' and 'start' in both cases should should be following on from the previous word as there's enough space.

    any suggestions how to fix the extra line or the segmentation fault or the last word problem? or the whole thing? any suggestions much appreciated. thanks.
  2. #2
  3. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2000
    Location
    Southern California
    Posts
    73
    Rep Power
    15
    Here's one way to do it:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    
    #define MAX_LINE     256
    #define MAX_LINE_LEN 20
    
    int readline(char buffer[], int max)
    {
        char c;
        int i=0;
    
        while (i < max && (c = getchar()) != EOF && c != '\n')
          buffer[i++] = c;
    
        buffer[i] = 0x00;   /* null-terminate */
        return i;
    }
    
    int main(int argc, char* argv[])
    {
      char buf[MAX_LINE_LEN+1];
      char *bufptr, *word;
      const char delim[] = " \t.,;:!-";
    
      int line_len=0, word_len=0;
    
      // read user input
      while (readline(buf, MAX_LINE)) {
        bufptr   = buf;
        line_len = word_len = 0;
    
        // tokenize the string
        while (word = strsep(&bufptr, delim)) {
    
          // ignore non-alphanumeric tokens
          if (strlen(word) == 1 && !isalpha(*word))
            continue;
    
          // determine length of current word
          for (word_len=0; word[word_len] != '\0'; word_len++)
            ;
    
          if (word_len > MAX_LINE_LEN) 
            printf("\nERROR: word length exceeds max line length\n");
    
          if (line_len == 0) {
            // this is the first word
            printf("%s", word);
            line_len += word_len;
          }
          else {
            // +1 is for the space we'll add
            line_len += word_len + 1;
    
            // if len is now > max, start a new line
            if (line_len > MAX_LINE_LEN) {
              printf("\n%s", word);
              line_len = word_len;
            }
            else {
              // print a space and the word
              printf(" %s", word);
            }
          }
        }
    
        printf("\n\nRead another line? (y/n): ");
        readline(buf, MAX_LINE);
    
        if (toupper(buf[0]) != 'Y')
            break;
    
        fpurge(stdin);
      }
    
      exit(EXIT_SUCCESS);
    }
    Last edited by vpopper; January 9th, 2003 at 02:01 PM.
  4. #3
  5. No Profile Picture
    .
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2002
    Posts
    296
    Rep Power
    13
    ok thanks very much, i haven't gone over it yet but will do.

IMN logo majestic logo threadwatch logo seochat tools logo