Search code examples
ctextformatjustify

C program to format text


I am given a string with a lot of spaces between words. I must write a program that transforms the given string into a text, with each line having no more than 80 characters. No word should be split and justify must be used. No additional libraries or functions to be used! I need help finishing the problem.

Example input: "John     had  a lot          of work to do."
Result:"John had
        a lot of
        work  to
              do"

In the example obviously I didn't use the 80 charaters rule, but rather 8. My code this far, eliminates the extra spaces and can calculate the length of the string.

#include <stdio.h>

int main()
{
   char text[1000], blank[1000],rez[1000];
   int n,i;
   printf("give string\n");
   gets(text);
   blankremove(text,blank);
   printf("%s\n",blank);
   n=lenght(blank);
   printf("%d", n);

   return 0;
}

int lenght(char a[]){
int lenght;
lenght=0;
while (a[lenght]!='\0')
{
    lenght++;
}
return lenght;
}

int blankremove(char text[], char blank[])
{

   int c = 0, d = 0;
   while (text[c] != '\0') {
      if (text[c] == ' ') {
         int temp = c + 1;
         if (text[temp] != '\0') {
            while (text[temp] == ' ' && text[temp] != '\0') {
               if (text[temp] == ' ') {
                  c++;
               }
               temp++;
            }
         }
      }
      blank[d] = text[c];
      c++;
      d++;
   }
   blank[d] = '\0';}

Solution

  • (This sounds like homework to me. Keep in mind the teacher has access to Stackoverflow, as well.)

    Let's see, your formatting is ... regrettable but that is not what you are asking.

    I think this will do what you need.

    Add these lines just before the return in main:

    fillLine(blank,rez,sizeof(rez));
    printf("%s\n", rez);
    

    Then create a function called fillLine that will look to see what will fit and put it on the line, if it will fit.

    /* Find the length of the next word on the line, upto the next space.
     */
    int lenWord(char *in)
    {
        int ii;
        for(ii=0; in[ii]!=0 && in[ii]!=' '; ii++);
        return(ii);
    }
    #define MAX_COLUMNS 16
    /*
     * This will stuff what it can in MAX_COLUMNS columns
     */
    int fillLine(char *blank, char *rez, int rezSize)
    {
        int in;
        int out;
        int col;
        for(col=0, in=0, out=0; blank[in]!=0 && out<rezSize;) {
            int len=lenWord(&blank[in]);
            if(col+len+1 < MAX_COLUMNS ) {
                int ii;
                for(ii=0; ii<len; ii++) {
                    rez[out]=blank[in];
                    in++;
                    out++;
                    col++;
                }
                rez[out]=' ';
                in++;
                out++;
                col++;
            } else {
                rez[out]='\n';
                out++;
                col=0;
            }
        }
        return(out);
    }
    

    This version has a few problems (that I suggest you resolve before turning it in):

    1. I passed the size of the output rez area to the function but don't check it enough to make sure I am not going beyond the end and trashing something else.
    2. I leave a blank at the end of all the lines which means they are not as filled as they might be.
    3. The fillLine function could be combined with your blankRemove function to make the program more concise.
    4. Some people prefer to put the constants on the left in the equality check in case there is a typo: 0!=in[ii] not in[ii]!=0. This helps to avoid the potential for if( in[ii]=0) {. Some people get excited about Yoda Conditions, both for and against.

    This will give you the idea. I might comment that using variables like ii rather than i makes it easier to search for them in the text editor.