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 column of input. Make sure your program does something intelligent with very long lines, and if there are no blanks or tabs before the specified column.

Source:

#include <stdio.h>
#include <wchar.h>

#define MAX_STRING_LENGTH 1024
#define LONG 80

typedef signed char bool;
#define TRUE 1
#define FALSE 0;

int parse_string(wchar_t input_string[MAX_STRING_LENGTH])
{
  int i;
  int o;
  
  /* how many blanks we have seen so far for this line. */
  int blank_counter = 0;
  /* out position in the current line. */
  int position = 0;

  wchar_t temp_string[MAX_STRING_LENGTH];

  /* copy original to the temp. */
  for(i = 0; input_string[i] != L'\0'; i++)
  {
    temp_string[i] = input_string[i];

    //printf("i=%i, input_string[i]=%c\n", i, temp_string[i]);
  }
  i++;
  temp_string[i] = L'\0';

  /* now parse. */

  /* pass 1
   * 
   * if we pass LONG and spaces are detected the we roll back through the string and replace
   * the last space with a newline. 
   */
  for(i = 0; temp_string[i] != L'\0'; i++)
  {
    //printf("position=%i\n", position);

    /* first let's look for spaces. */
    if(temp_string[i] == L' ')
    {
      blank_counter++;
    }

    /* Then let's see if we have exceeded LONG (and blanks have been entered.) */
    if((position > LONG) && (blank_counter > 0))
    {
      //printf("LONG with blanks tripped!\n");

      /* clear the blank counter. */
      blank_counter = 0;

      /* roll back our string until a space is found and replace it with a newline. */
      do
      {
        i--;
      }
      while(temp_string[i] != L' ');
      temp_string[i] = L'\n';
      i++;

      position = -1;
    }

    /* if we have passed the LONG mark with no blanks then reset position
     * since the next pass will be creating a newling for us. 
     */
    if((position > LONG) && (blank_counter == 0))
    {
      position = -1;
    }
    position++;
  }


  /* parse the string a second time for long words with no spaces. */

  // reset position. 
  position = 0;

  // reset i and o.
  i = 0;
  o = 0;

  // reset the blank_counter.
  blank_counter = 0;

  /* copy temp to the orignal. 
  for(i = 0; temp_string[i] != L'\0'; i++)
  {
    input_string[i] = temp_string[i];

    //printf("i=%i, input_string[i]=%c\n", i, temp_string[i]);
  }
  i++;
  input_string[i] = L'\0';
  */

  // run through the string a make sure there is now word that is too long.
  while(input_string[i] != L'\0')
  {
    // look for spaces.
    if(temp_string[i] == L' ')
    {
      blank_counter++;
    }

    // if a newline is reached reset the postion and move on. 
    if(temp_string[i] == L'\n')
    {
      input_string[o] = temp_string[i];
      i++;
      o++;

      position = 0;
      blank_counter = 0;
    }

    // test position. Make sure to trip on LONG-1 to make room for the - symbol. 
    if((position >= (LONG-1)) && (temp_string[i+1] != L'\0') && (blank_counter == 0))
    {
      // insert a semicolon and newline.
      input_string[o] = L'-';
      o++;
      input_string[o] = L'\n';

      position = 0;
    }
    else
    {
      input_string[o] = temp_string[i];
      //printf("i=%i, o=%i, input_string[o]=%c\n", i, o, input_string[o]);
      i++;
      position++;
    }
    o++;
    //printf("at end position=%i\n", position);
  }
  // make sure the string ends properly. 
  i++;
  input_string[i] = L'\0';

  return 0;
}

print_string(wchar_t input_string[MAX_STRING_LENGTH])
{
  int i;

  /* I check ahead to skip the newline?. */
  for(i = 0; input_string[i+1] != L'\0'; i++)
  {
    printf("%c", input_string[i]);
  }
  printf("\n");

  return 0;
}
    
int clear_string(wchar_t input_string[MAX_STRING_LENGTH])
{
  int i;

  for(i = 0; i < MAX_STRING_LENGTH; i++)
  {
    input_string[i] = '\0';
  }

  return 0;
}

int main(int argc, char *argv[])
{
  int i = 0;
  int o = 0;

  wchar_t input_string[MAX_STRING_LENGTH];
  wchar_t stored_string[MAX_STRING_LENGTH];

  bool running = TRUE;
  bool get_sentence = TRUE;

  /* our intoduction. */
  printf("Enter a sentence smaller than %i characters and I will format it so that it\n"
      "will not exceed %i characters per line. [ctrl]+[d] to exit.\n", MAX_STRING_LENGTH, LONG);
  for(i = 0; i < LONG; i++)
  {
    printf(" ");
  }printf("v\n");
  printf("________________________________________________________________________________\n"); 

  while(running)
  {
    /* reset our counter. */
    i = 0;

    /* clear the string. */
    clear_string(input_string);

    /* get a sentence. */
    while(get_sentence)
    {
      input_string[i] = getchar();
      //printf("%c", input_string[i]);

      if(input_string[i] == EOF)
      {
        get_sentence = FALSE;
        running = FALSE;
      }
      
      if(input_string[i] == L'\n')
      {
        printf("________________________________________________________________________________\n"); 
        get_sentence = FALSE;

        /* parse string. */
        parse_string(input_string);

        /* and print it. */
        print_string(input_string);
        
        /* and clear it. */
        clear_string(input_string);

        printf("________________________________________________________________________________\n"); 
      }
      i++;
    }

    /* get another sentence. */
    if(running)
    {
      get_sentence = TRUE;
    }
  }


  return 0;
}
Output
Enter a sentence smaller than 1024 characters and I will format it so that it
will not exceed 80 characters per line. [ctrl]+[d] to exit.
                                                                                v
________________________________________________________________________________
This is just a test of my program that will break up really long sentences so that they don't get too long.
________________________________________________________________________________
This is just a test of my program that will break up really long sentences so
that they don't get too long.
________________________________________________________________________________
Ithandleslongstringstoothathavenospacesandjustkeepgoingandgoingsoitusesahyphentobreakupthesentence
________________________________________________________________________________
Ithandleslongstringstoothathavenospacesandjustkeepgoingandgoingsoitusesahyphent-
obreakupthesentence
________________________________________________________________________________

Notes:

I had a lot of trouble with this one. I spent a long time fighting my console feeding random input into the first getchar loop. I just ended up rewriting the thing from scratch. You will notice I'm still using long character support with stuff like: L'-' to indicate a LONG character and not standard ASCII. This seems to work well enough. The program will take UTF8 characters and spit them back out at me. When I tested beyond LONG with unicode it formatted oddly but did not crash. I'm not sure if that is becuase of my console or unicode support or my code. I have no real way to easily test it.