Листинг обработок строк в С++

Тема:  Обработка символьных массивов

Задание

Во введенном предложении расположите слова в обратной последовательности. Порядок следования знаков препинания не менять.
В предложении используются русские буквы и знаки.

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>

#define N 20

  //  ПРЕДВАРИТЕЛЬНОЕ ОБЪЯВЛЕНИЕ ФУНКЦИЙ
  // Заголовок программы
      void Title();
  // Ввод предложения
      void InpPredl (char predl[]);
  // Выделение из предложения
     void Select(const char *predl, char m[][N],char *sel, int *n);
  // Сборка предложения
     char *Constructor(char slova[][N], char razd[][N], int sl, int rz);
  // Вывод результата
     void OutPredl(char *s1, char *s2);

inline void rus()  // Русификация вывода в консольное окно
{
    //setlocale( LC_CTYPE, ".1251" );
    //setlocale( LC_MONETARY, ".1251" );
    setlocale( LC_ALL, "" );
}

// ОСНОВНАЯ ФУНКЦИЯ
int main()
{
     // ОБЪЯВЛЕНИЕ ПЕРЕМЕННЫХ
  char predl[80];    // Введенное предложение
  char *res;            // Результирующее предложение
  char slova[N][N]; // Массив слов в предложении
  char razd [N][N]; // Массив разделителей в предложении
  int  sl=-1, rz=-1;  // Счетчики слов и разделителей
  char buk[80]; // все буквы алфавита
  char *bs="йцукенгшщзхъфывапролджэячсмитьбю";// Буквы строчные
  char *bz ="ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ";/*  заглавные */
  char *r="`!;:,.?- _";         // Разделительные знаки
//ВЫЗОВ ФУНКЦИЙ НА ИСПОЛНЕНИЕ
    rus();
// Заголовок программы
       Title ();
  // Ввод предложения
       InpPredl (predl);
  // Выделение из предложения слов
      Select (predl, slova, r, &sl);
  // Выделение из предложения разделителей
      strcpy(buk,"");
      strcat (buk, bs);
      strcat (buk, bz);
      Select (predl, razd, buk, &rz);
  // Сборка предложения
      res = Constructor(slova, razd, sl, rz);
  // Вывод результата
     OutPredl (predl, res);
  free (res);
    return 0;
}


// ОПИСАНИЕ ИСПЛЬЗУЕМЫХ ФУНКЦИЙ
// Заголовок программы
void Title()
{
  puts (" Задание  по теме\n");
  
}
// Ввод предложения
void InpPredl(char *s)
{
  puts("Введите предложение \n");
  strcpy (s,"Верите ли вы, что задача решена?");
  // gets (s);
}
// Вывод результата
void OutPredl (char *s1, char *s2)
  {
    puts ("Исходное предложение");
    puts (s1);
    puts (" Результат ");
    puts (s2);
  }
// Выделение из предложения
void Select(const char *predl, char m[][N], char *sel, int *n)
{
  char *p, *s;

  s=strdup (predl); // Сделать копию исходного предложения
	// так как передается константа, strtok требует
	// внесения изменений при своей работе
  p = strtok (s, sel);
  while (p)
    {
     (*n)++;
     strcpy (m[*n],p);
     p = strtok (NULL, sel);
    }
  free (s);
}
// Сборка предложения
char *Constructor(char slova[][N], char razd[][N], int sl, int rz)
{
  int i, j;
  char res[80];
  char *s;
*res=0; // Начальное значение результата
   i = sl;
   j=-1;
  while ((i>=0)||(j<=rz))
    {
      if ((i>=0)) strcat (res, slova[i]); // Добавление слова
      i--;
      j++;
      if ((j<=rz)) strcat (res, razd[j]); // Добавление знаков
    }
  s = strdup (res);
  return s;
}