Question

At the end of Chapter 1 of The C Programming Language, there are a few exercises to complete. The one I am doing now asks you to make a program that wraps a long string of text into multiple lines at a specific length. The following function works 100%, aside from the last line which does not get wrapped, no matter the specified maximum width of a line.

// wrap: take a long input line and wrap it into multiple lines
void wrap(char s[], const int wrapline)
{
    int i, k, wraploc, lastwrap;

    lastwrap = 0; // saves character index after most recent line wrap
    wraploc = 0; // used to find the location for next word wrap

    for (i = 0; s[i] != '\0'; ++i, ++wraploc) {

        if (wraploc >= wrapline) {
            for (k = i; k > 0; --k) {
                // make sure word wrap doesn't overflow past maximum length
                if (k - lastwrap <= wrapline && s[k] == ' ') {
                    s[k] = '\n';
                    lastwrap = k+1;
                    break;
                }
            }
            wraploc = 0;
        }

    } // end main loop

    for (i = 0; i < wrapline; ++i) printf(" ");
    printf("|\n");
    printf("%s\n", s);
}

I have found the issue to be with the variable wraploc, which is incremented until it is greater than wrapline (the maximum index of a line). Once it is greater than wrapline, a newline is inserted at the appropriate location and wraploc is reset to 0.

The problem is that on the last line, wraploc is never greater than wrapline, even when it should be. It increments perfectly throughout iteration of the string, until the last line. Take this example:

char s[] = "This is a sample string the last line will surely overflow";
wrap(s, 15);

$ ./a.out
               |
this is a
sample string
the last line
will surely overflow

The line represents the location where it should be wrapped. In this case, wraploc has the value 14, when there are clearly more characters than that.

I have no idea why this is happening, can someone help me out?

(Also I'm a complete beginner to C and I have no experience with pointers so please stay away from those in your answers, thanks).

Was it helpful?

Solution

You increment wraploc with i until it reaches wrapline (15 in the example).
When you wrap, you backtrack from i, back to the last whitespace.
That means that in your next line you already have some characters between the lastwrap location and i, i.e., you can't reset wraploc to 0 there.
Try setting wraploc = i-lastwrap instead.

OTHER TIPS

Anybody who might, like me, find this question and run into a problem with new-lines in the source string.

This is my answer:

inline int wordlen(const char * str){
   int tempindex=0;
   while(str[tempindex]!=' ' && str[tempindex]!=0 && str[tempindex]!='\n'){
      ++tempindex;
   }
   return(tempindex);
}
void wrap(char * s, const int wrapline){

   int index=0;
   int curlinelen = 0;
   while(s[index] != '\0'){

      if(s[index] == '\n'){
         curlinelen=0;
      }
      else if(s[index] == ' '){

         if(curlinelen+wordlen(&s[index+1]) >= wrapline){
            s[index] = '\n';
            curlinelen = 0;
         }

      }

      curlinelen++;
      index++;
   }

}

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top