Вывести на экран слова, отличающиеся лишь порядком следования букв - C (СИ)

Формулировка задачи:

Всем здрасте! Заранее спасибо, если Вы даже просто подумали над моей проблемкой. В общем, к делу. Задача была таковой: Дана строка (неизвестной длины) - вывести на экран слова (из данной строки), которые отличаются лишь порядком следования букв (мама - амма - амам и т.д.). Я долго бился над решением и решил, что это можно сделать следующим образом: разделить строку на слова, в каждом слове буквы свести к одному регистру и отсортировать в алфавитном порядке(написал для этого функцию). Затем каждое слово сравнить таким образом с остальными и, как только найдется "пара" - вывести на экран. Вот мое скудное (наверняка некрасивое), но творение:
#include <locale>
#include <stdio.h>
#include <stddef.h>
#include <cstdio>
#include <conio.h>
#include <iostream>
#include <string.h>
 
#define maxn 10000
 
char S[maxn], *NewWord, **Words;
int i,f,N, WBeg,WEnd,WLeng, Numb, col, row, z;
 
 
char *expansion (char *Word) {char *FuncAr; char C; int j;
                                j=0;
                                while (Word[j]!='\0') j++;
                                FuncAr=(char*)calloc(j, sizeof (char));
 
                                for (int k = 0;k<=j;k++) FuncAr[k]=Word[k];
                                FuncAr=strlwr(FuncAr);
                                j=1;
                                while (j=1) {
                                    j=0;
                                for (int k=1; k<=i;k++) { if (FuncAr[k]<FuncAr[k-1]) {j=1;
                                                        C=FuncAr[k];
                                                        FuncAr[k]=FuncAr[k-1];
                                                        FuncAr[k-1]= C;}}}
                                puts (FuncAr);
                                return FuncAr;
                        }
 
void main ()
{
    setlocale (0,"russian");
    do{
       printf ("Введите вашу строку!\n");
       gets_s (S);
       i=0;
       N=1;
    
       while (S[i]!='\0' && N==1) 
       {if ((S[i]!=' ') && ! ((S[i]>='A' && S[i]<='Z') || (S[i]>='a' && S[i]<='z'))) /*|| ((unsigned char)S[i]>=(unsigned char)'А' && (unsigned char)S[i]<=(unsigned char)'я')*/
           N=0;
        i++;
       }
        
       if (N==0) printf ("Ввод некорректен. Попробуйте заново\n");
        
      }while (N==0);
    N=i;
    i=0;
    
     Words = (char**)calloc(N, sizeof(*Words));
     Numb=1;
 
    while (i<=N) 
    { 
     while (S[i]==' ') i++;
     WBeg=i;
     while (S[i]!=' ') i++;
     WEnd=i;
 
     WLeng=WEnd-WBeg;
    
     Words[Numb]=(char*)calloc(WLeng, sizeof(char));
 
     for (int k = 0, i=WBeg;i<=WEnd; i++, k++) {
         Words[Numb][k]=S[i];}
     Numb++;
 
     printf ("Слово № %d :\n", Numb);
     puts (Words[Numb]);
     printf ("\n\n");
    }
    printf ("Результат:\n");
 
    row=1;
    while (row<=Numb) {
        for (i=0;i<=Numb;i++) {if (strcmp(expansion(Words[row]),expansion(Words[i]))) puts(Words[row]);}
        row++;}
free (Words);
system ("pause");
}
Прошу прощения за такое большое количество переменных, не обессудьте. У меня здесь две проблемы (ну.. пока те, на которые я наткнулся) - 1)Не распознает слова = не выводит их на экран по отдельности (Выдает ошибку, вида "бла-бла-бла, адрес программы. Строка 49. Выражение (string !=NULL). бла-бла-бла") 2) Какая-то глупая ошибка в функции сортировки слова (или не глупая... я ее, в общем, найти не могу).. Прошу помощи, если вам не трудно) Я писал пока только для латинских букв.. и в строке не может быть ничего, окромя латинских букв и пробелов.. Потом, как с вашей божьей помощью разберусь с тем, что здесь неверно, пойду разбираться с русскими буквами и знаками препинания. Еще раз спасибо за внимание!

Код к задаче: «Вывести на экран слова, отличающиеся лишь порядком следования букв - C (СИ)»

textual
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
//создаем массив из слов введенной строки
char **CreateArray(char line[], int len, int *cnt) {
    int i = -1;
    int count = 0;
    char *buf = (char*) malloc(strlen(line) + 1); //копия исходной строки, уничтожается в процессе подсчета слов
    strcpy(buf, line);
 
    char *delims = " ,.-\n";
    char *word = strtok(buf, delims);
    while (word != NULL) {
        ++count;                                  //считаем фактическое кво слов
        word = strtok(NULL, delims);
    }
    free(buf);
    *cnt = count;
    char **words = (char**) malloc(count * sizeof(char*)); //выделяем память под count слов длиной len
    while (++i < count)
        words[i] = (char*) malloc(len);
 
    word = strtok(line, delims); //заполняем массив словами из строки
    i = -1;
    while (word != NULL) {
        strcpy(words[++i], word);
        word = strtok(NULL, delims);
    }
    return words;
}
 
//печать массива слов
void ShowArray(char **words, int count) {
    int i = -1;
    while (++i < count)
        printf("%s\n", words[i]);
}
 
//копия массива слов
char **CopyArray(char **words, int count) {
    int i = -1;
    char **copy = (char**) malloc(count * sizeof(char*));
    while (++i < count) {
        copy[i] = (char*) malloc(strlen(words[i]) + 1);
        strcpy(copy[i], words[i]);
    }
    return copy;
}
 
//очистка памяти
void DestroyArray(char **words, int count) {
    while (--count > -1)
        free(words[count]);
    free(words);
}
 
//своп двух букв для сортировки по алфавиту
void Swap(char *a, char *b) {
    char t = *a;
    *a = *b;
    *b = t;
}
 
//сортировка слова по алфавиту
void SortLetters(char *word) {
    int i, j, len = strlen(word);
    for (i = 0; i < len - 1; i++)
        for (j = i + 1; j < len; j++)
            if (word[j] < word[i])
                Swap(&word[i], &word[j]);
}
 
//собственно, решение задачи
void FindBros(char **words, int count) {
    int i, j;
 
    char **copy = CopyArray(words, count);          //создаем копию массива слов
    for (i = 0; i < count; i++)
        SortLetters(copy[i]); //в каждом слове переставляем все буквы по алфавиту
 
    int *mask = (int*) malloc(count * sizeof(int)); //маска: слово уже было найдено как "двойник по буквам" или нет
    for (i = 0; i < count; i++)
        mask[i] = 0;                                    //сначала - все 0
 
    for (i = 0; i < count - 1; i++) {
        if (!mask[i])        //если i-ое слово еще не было "двойником по буквам"
        {
            printf("\n%20s: ", words[i]);
            for (j = i + 1; j < count; j++)
                if (strcmp(copy[i], copy[j]) == 0) //сравниваем i-ую и j-ую копию, т.е. буквенный состав слов words[i] и words[j]
                        {
                    printf("%20s ", words[j]); //если буквенный состав совпал - выводим words[j]
                    mask[j] = 1; //в маске помечаем j-ое слово как уже найденное в качестве "двойника"
                }
        }
    }
 
    DestroyArray(copy, count);
    free(mask);
}
 
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int main() {
    char str[BUFSIZ];
    int len = 20, count = 0;
    printf("Your string:\n");
 
    fgets(str, BUFSIZ, stdin);
 
    char **words = CreateArray(str, len, &count);
    printf("\n\nYour words:\n");
    ShowArray(words, count);
 
    printf("\n\nWords with the same set of letters:\n");
    FindBros(words, count);
 
    DestroyArray(words, count);
    getchar();
    return 0;
}

14   голосов, оценка 4.000 из 5


СОХРАНИТЬ ССЫЛКУ