• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Modyfikacja tesktów

Object Storage Arubacloud
0 głosów
198 wizyt
pytanie zadane 4 czerwca 2020 w C i C++ przez Hubertius Bywalec (2,970 p.)

Hej :)

Wykonuję właśnie takie oto zadanie:

Napisz i przetestuj funkcję text_modifier przetwarzającą tekst na szereg wybranych sposobów i zwracającą tablicę wygenerowanych tekstów (po przetworzeniu) Przykładowe wywołanie funkcji powinno wyglądać następująco:

const char* text = "Ala ma kota";
char **res = text_modifier(text, 2, lower_to_upper, upper_to_lower);
Funkcja ma przyjmować w parametrach:

tekst do modyfikacji,
liczbę funkcji modyfikujących tekst oraz
wskaźniki na kolejne funkcje.
W przypadku sukcesu funkcja powinna zwrócić tablicę zmodyfikowanych tekstów. Koniec tablicy ma być oznaczony wartością NULL. Kolejne wiersze to kolejne wersje tekstu wejściowego, zmodyfikowane za pomocą funkcji przekazanej w parametrze.

W przypadku błędnych danych wejściowych lub problemów z alokacją pamięci funkcja powinna zwrócić NULL.

Każdy kolejny wiersz w tablicy wyjściowej (zwracanej) ma odpowiadać wejściowemu napisowi przekształconemu kolejną (jedną) funkcją z listy parametrów.

Przygotuj funkcje do modyfikacji tekstu in. Funkcje powinny przyjmować tekst oraz zwracać wskaźnik na nowy, zmodyfikowany tekst. Prototypy funkcji mają wyglądać następująco:

char* lower_to_upper(const char *in);
char* upper_to_lower(const char *in);
char* space_to_dash(const char *in);
char* reverse_letter(const char *in);
Funkcja lower_to_upper zmienia wielkość liter w tekście in na duże.
Funkcja upper_to_lower zmienia wielkość liter w tekście in na małe.
Funkcja space_to_dash zmienia spacje w tekście in na podłogi.
Funkcja reverse_letter odwraca litery w tekście in na przeciwne w alfabecie. Funkcja zmienia a na z, B na Y, itd).
Dodatkowo przygotuj funkcję do zwalniania pamięci przydzielonej na tablicę tekstów:

void free_texts(char **);
Jeżeli dane przekazane do funkcji są niepoprawne, to ta nie podejmuje żadnej akcji.

Program powinien na początku przygotować (zaalokować):

tablicę na tekst wprowadzany od użytkownika (1000 znaków, alokowany dynamicznie),
4-elementową tablicę wskaźników na wskaźniki na funkcje konwersji tekstów oraz
4-elementową tablicę liczb całkowitych int , do przechowywania wyborów wprowadzonych przez użytkownika.
W przypadku niepowodzenia alokacji pamięci program powinien wyświetlić komunikat Failed to allocate memory i zakończyć działanie z kodem błędu 8.
Program powinien pobrać od użytkownika tekst, następnie liczbę operacji, które mają być wykonane na przekazanym tekście (od 2 do 4) a ostatecznie identyfikatory poszczególnych operacji:

0 - zamiana małych liter na duże,

1 - zamiana dużych liter na małe,

2 - odwracanie liter w tekście,

3 - zamiana spacji na podłogi.

W przypadku wprowadzenia błędnych znaków program powinien wyświetlić komunikat Incorrect input i zakończyć działanie z kodem błędu 1.

W przypadku błędnych danych wejściowych komunikat Incorrect input data i zakończyć działanie z kodem błędu 2.

W przypadku sukcesu program powinien wyświetlić, w kolejnych liniach teksty, będące modyfikacją tekstu podanego przez użytkownika.

Przykładowa interakcja z programem -- sukces:

Podaj tekst do przeksztalcenia: Man is least himself when he talks in his own person. Give him a mask, and he will tell you the truth. - Oscar Wilde⏎
Podaj liczbe operacj do przeprowadzenia: 3⏎
Podaj wybrane operacje: 1 0 3 ⏎
man is least himself when he talks in his own person. give him a mask, and he will tell you the truth. - oscar wilde⏎
MAN IS LEAST HIMSELF WHEN HE TALKS IN HIS OWN PERSON. GIVE HIM A MASK, AND HE WILL TELL YOU THE TRUTH. - OSCAR WILDE⏎
Man_is_least_himself_when_he_talks_in_his_own_person._Give_him_a_mask,_and_he_will_tell_you_the_truth._-_Oscar_Wilde⏎
Podaj tekst do przeksztalcenia: Books are mirrors: you only see in them what you already have inside you. - Carlos Ruiz Zafon⏎
Podaj liczbe operacj do przeprowadzenia: 2⏎
Podaj wybrane operacje: 1 0 ⏎
books are mirrors: you only see in them what you already have inside you. - carlos ruiz zafon⏎
BOOKS ARE MIRRORS: YOU ONLY SEE IN THEM WHAT YOU ALREADY HAVE INSIDE YOU. - CARLOS RUIZ ZAFON⏎
Przykładowa interakcja z programem -- brak pamięci:

Limit sterty: 532 bajty

Failed to allocate memory⏎
Limit sterty: 1049 bajtów

Podaj tekst do przeksztalcenia: It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration. - Edsger Dijkstra⏎
Podaj liczbe operacj do przeprowadzenia: 4⏎
Podaj wybrane operacje: 2 1 2 3 ⏎
Failed to allocate memory⏎

Na razie jestem na etapie funkcji i rozpisałem to w ten sposób:

char* lower_to_upper(const char *in)
{
    if( in == NULL )
    {
        return NULL;
    }
    int sizeof_for_buffer= (strlen(in) + 1);
    char * score = (char *) malloc(sizeof(char) *sizeof_for_buffer);
    if( score == NULL )
    {
        return NULL;
    }
    int i = 0;
    while( *(in + i) != '\0' )
    {
        if( *(in + i)>= 97 && *(in + i) <= 122  )
        {
            *(score + i) = *(in + i) - 32;
        }
        else
        {
            *(score + i) = *(in + i) ;
        }
        i++;
    }
    *(score + i) = '\0';
    return score;

}

char* upper_to_lower(const char *in)
{
    if( in == NULL )
    {
        return NULL;
    }
    int sizeof_for_buffer= (strlen(in) + 1);
    char * score = (char *) malloc(sizeof(char) *sizeof_for_buffer);
    if( score == NULL )
    {
        return NULL;
    }
    int i = 0;
    while( *(in + i) != '\0' )
    {
        if( *(in + i) >= 65 && *(in + i) <= 90  )
        {
            *(score + i) = *(in + i) + 32;
        }
        else
        {
            *(score + i) = *(in + i) ;
        }
        i++;
    }
    *(score + i) = '\0';
    return score;
}
char* space_to_dash(const char *in)
{
    if( in == NULL )
    {
        return NULL;
    }
    int sizeof_for_buffer= (strlen(in) + 1);
    char * score = (char *) malloc(sizeof(char) *sizeof_for_buffer);
    if( score == NULL )
    {
        return NULL;
    }
    int i = 0;
    while( *(in + i) != '\0' )
    {
        if( *(in + i) == ' '  )
        {
            *(score + i) = '_';
        }
        else
        {
            *(score + i) = *(in + i);
        }
        i++;
    }
    *(score + i) = '\0';
    return score;
}
char* reverse_letter(const char *in)
{
    if( in == NULL )
    {
        return NULL;
    }
    int sizeof_for_buffer= (strlen(in) + 1);
    char * score = (char *) malloc(sizeof(char) *sizeof_for_buffer);
    if( score == NULL )
    {
        return NULL;
    }
    int i = 0;
    while( *(in + i) != '\0'  )
    {
        if( *(in + i) >= 65 &&  *(in + i) <= 90 )
        {
            *(score + i) = 65 - *(in + i) + 90;
        }
        else if( *(in + i) >= 97 &&  *(in + i) <= 122 )
        {
            *(score + i) = 97 - *(in + i) + 122;
        }
        else
        {
            *(score + i) = *(in + i);
        }
        i++;
    }
    *(score + i) = '\0';
    return score;
}

void free_texts(char ** table_of_texts)
{
    if( table_of_texts == NULL )
    {

    }
    else
    {
        int i = 0;
        while( *(table_of_texts + i) != NULL  )
        {
            free(*(table_of_texts + i));
            i++;
        }
        free(table_of_texts);
    }

}

Na tą chwilę najwięcej problemów mam z funkcją text_moddifier. Mam jej dwie wersje:

char **text_modifier(const char *text, int how_many, ...)
{
    if( text == NULL || how_many <= 0 )
    {
        return NULL;
    }
    char ** result = (char **) malloc( sizeof(char *) * 5 );
    int i = 0;
    for(i = 0; i < 5; i++)
    {
        *(result + i) = NULL;
    }
    va_list list_1;
    va_start(list_1,how_many);
    char * (*pointer_on)(const char *);
    for(i = 0; i < how_many; i++)
    {
        pointer_on = va_arg(list_1, char * (*)(const char *));
        if( pointer_on == lower_to_upper || pointer_on == upper_to_lower || pointer_on == space_to_dash || pointer_on == reverse_letter )
        {
            if( pointer_on == lower_to_upper )
            {
                *(result + i) = lower_to_upper(text);
            }
            if( pointer_on == upper_to_lower )
            {
                *(result + i) = upper_to_lower(text);
            }
            if( pointer_on == space_to_dash )
            {
                *(result + i) = space_to_dash(text);
            }
            if( pointer_on == reverse_letter )
            {
                *(result + i) = reverse_letter(text);
            }
        }
        else
        {
            va_end(list_1);
            int j = 0;
            while( *(result + j) != NULL  )
            {
                free( *(result + j)  );
                j++;
            }
            free(result);
            return NULL;
        }
    }
    va_end(list_1);
    return result;
}

Tutaj jednak przy pierwszym teście funkcyjnym pokazuje mi taką informację:

TEST 25: Sprawdzanie poprawności działania funkcji text_modifier - (limit sterty ustawiono na 108 bajtów)⏎
Wynik: PORAŻKA: Funkcja text_modifier() powinna zwrócić adres zaalokowanej pamięci, a zwróciła NULL⏎
       Sprawdź funkcję testującą TEST25(void) z pliku unit_test_v2.c, w linii 1127⏎

A dla drugiej wersji:

char **text_modifier(const char *text, int how_many, ...)
{
    if( text == NULL || how_many <= 0 )
    {
        return NULL;
    }
    char ** result = (char **) malloc( sizeof(char *) * 5 );
    int i = 0;
    for(i = 0; i < 5; i++)
    {
        *(result + i) = NULL;
    }
    va_list list_1;
    va_start(list_1,how_many);
    char * (*pointer_on)(const char *);
    for(i = 0; i < how_many; i++)
    {
        pointer_on = va_arg(list_1, char * (*)(const char *));
        *(result + i) = pointer_on(text);
        if( *(result + i) == NULL )
        {
            va_end(list_1);
            int j = 0;
            while( *(result + j) != NULL  )
            {
                free( *(result + j) );
                j++;
            }
            free(result);
            return NULL;
        }
    }
    va_end(list_1);
    return result;
}

Pokazuje mi takie wyniki:

TEST 25: Sprawdzanie poprawności działania funkcji text_modifier - (limit sterty ustawiono na 58 bajtów)⏎
Wynik: PORAŻKA: Pod indeksem 219025168 powinna zostać zapisana wartość NULL⏎
       Sprawdź funkcję testującą TEST25(void) z pliku unit_test_v2.c, w linii 1118⏎
Analiza zasobów: PORAŻKA dla functions.c:206: Próba zwolnienia niezaalokowanego wcześniej bloku pamięci (nieznany wskaźnik)⏎

Dostałem informację od prowadzącego, że druga wersja jest najbliższa prawdy. Jak sądzicie, co tu muszę poprawić?

komentarz 4 czerwca 2020 przez Hubertius Bywalec (2,970 p.)

Jak coś dostałem jeszcze taką informację:

W przypadku sukcesu funkcja powinna zwrócić tablicę zmodyfikowanych tekstów. Koniec tablicy ma być oznaczony wartością NULL.

No dobrze, ale... co jeśli do funkcji zostanie przekazane how_many o wartości 4? Jeżeli rzeczywiście mam robić alokację na 4 wskaźniki to jak w przypadku 4 wskażę koniec tablicy jako NULL?

komentarz 4 czerwca 2020 przez mokrowski Mędrzec (155,460 p.)

W podobnym idiomie, text_transform (inny niż w poleceniu bo zwracający tylko 1 bufor i dbający o to by nie było wycieków), może wyglądać tak:

#include <stdio.h>
#include <string.h>
#include <stdarg.h> 
#include <stdlib.h>
#include <stdbool.h>

static bool is_lower(const char c) {
	return (c >= 'a') && (c <= 'z');
}

static bool is_upper(const char c) {
	return (c >= 'A') && (c <= 'Z');
}

static bool is_letter(const char c) {
	return is_lower(c) || is_upper(c);
}

static bool is_space(const char c) {
	return c == ' ';
}

static char toggle_letter(const char c) {
	return c ^ 0x20;
}

static char to_dash(const char c) {
	return '_';
}

static const char * change(const char * in, bool (*pred)(const char), char (*change_to)(const char)) {
	size_t str_size = strlen(in);
	if (str_size == 0) {
		goto EXIT1;
	}
	char * new_str = malloc((str_size + 1) * sizeof(*new_str));
	if (new_str == NULL) {
		goto EXIT1;
	}
	char * ptr = new_str;
	while(*in) {
		*ptr = pred(*in) ? change_to(*in): *in;
		++ptr;
		++in;
	}
	*ptr = '\0';
	return new_str;

EXIT1:
	return NULL;
}

typedef const char * (*func_type)(const char *);

const char * lower_to_upper(const char * in) {
	return change(in, is_lower, toggle_letter);
}

const char * upper_to_lower(const char * in) {
	return change(in, is_upper, toggle_letter);
}

const char * reverse_letter(const char * in) {
	return change(in, is_letter, toggle_letter);
}

const char * space_to_dash(const char * in) {
	return change(in, is_space, to_dash);
}

const char * text_transform(const char * in, size_t how_many, ...) {

	if ((how_many == 0) || (in == NULL)) {
		goto EXIT_NULL;
	}

	va_list func_list;
	va_start(func_list, how_many);

	const char * input = va_arg(func_list, func_type)(in);
	const char * result = NULL;

	for (size_t i = 1; i < how_many; ++i) {
		result = va_arg(func_list, func_type)(input);
		if (result == NULL) {
			goto EXIT_FREE_INPUT;
		}
		free((char *) input);
		input = result;
	}

	va_end(func_list);
	return input;

EXIT_FREE_INPUT:
	free((char *) input);
EXIT_NULL:
	return NULL;
}

int main(void) {
	const char * str = "Ala ma kota?!";

	const char * new_str = lower_to_upper(str);
	printf("%s\n", new_str);
	free((char *)new_str);

	new_str = upper_to_lower(str);
	printf("%s\n", new_str);
	free((char *)new_str);

	new_str = reverse_letter(str);
	printf("%s\n", new_str);
	free((char *)new_str);

	new_str = space_to_dash(str);
	printf("%s\n", new_str);
	free((char *)new_str);

	new_str = text_transform(str, 2, upper_to_lower, space_to_dash);
	printf("%s\n", new_str);
	free((char *)new_str);

	return 0;
}

 

2 odpowiedzi

+1 głos
odpowiedź 4 czerwca 2020 przez mokrowski Mędrzec (155,460 p.)
wybrane 5 czerwca 2020 przez Hubertius
 
Najlepsza

Hmm... a może by tak?

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

static bool is_lower(const char c) {
	return (c >= 'a') && (c <= 'z');
}

static bool is_upper(const char c) {
	return (c >= 'A') && (c <= 'Z');
}

static bool is_letter(const char c) {
	return is_lower(c) || is_upper(c);
}

static bool is_space(const char c) {
	return c == ' ';
}

static char toggle_letter(const char c) {
	return c ^ 0x20;
}

static char to_dash(const char c) {
	return '_';
}

static const char * change(const char * in, bool (*pred)(const char), char (*change_to)(const char)) {
	size_t str_size = strlen(in);
	if (str_size == 0) {
		goto EXIT1;
	}
	char * new_str = malloc((str_size + 1) * sizeof(*new_str));
	if (new_str == NULL) {
		goto EXIT1;
	}
	char * ptr = new_str;
	while(*in) {
		*ptr = pred(*in) ? change_to(*in): *in;
		++ptr;
		++in;
	}
	*ptr = '\0';
	return new_str;

EXIT1:
	return NULL;
}

const char * lower_to_upper(const char * in) {
	return change(in, is_lower, toggle_letter);
}

const char * upper_to_lower(const char * in) {
	return change(in, is_upper, toggle_letter);
}

const char * reverse_letter(const char * in) {
	return change(in, is_letter, toggle_letter);
}

const char * space_to_dash(const char * in) {
	return change(in, is_space, to_dash);
}

int main(void) {
	const char * str = "Ala ma kota?!";

	const char * new_str = lower_to_upper(str);
	printf("%s\n", new_str);
	free((char *)new_str);

	new_str = upper_to_lower(str);
	printf("%s\n", new_str);
	free((char *)new_str);

	new_str = reverse_letter(str);
	printf("%s\n", new_str);
	free((char *)new_str);

	new_str = space_to_dash(str);
	printf("%s\n", new_str);
	free((char *)new_str);

	return 0;
}

Funkcyjnie także da się pisać i w C :)

komentarz 4 czerwca 2020 przez Hubertius Bywalec (2,970 p.)
Ciekawy sposób rozwiązania, ale jednak do zaliczenia zadania muszę się posłużyć funkcją text_modifier. :(
1
komentarz 4 czerwca 2020 przez mokrowski Mędrzec (155,460 p.)
No i nie ma sprawy, także możesz to zrobić funkcyjnie :) trzeba tylko pamiętać by w text_modifier, uważnie zwalniać zaalokowane zasoby. No i masz (chyba już 2 raz), użyte va_* :)
+1 głos
odpowiedź 4 czerwca 2020 przez overcq Pasjonat (21,710 p.)
W drugiej wersji...

Dlaczego przydzielasz 5 rezultatów zamiast how_many + 1 ? Użyj funkcji calloc i od razu zeruje pamięć.

Dlaczego podczas zwalniania pamięci po otrzymaniu NULL nie wyliczasz od 0 do i - 1 zamiast sprawdzania za każdym razem NULL ?
komentarz 5 czerwca 2020 przez Hubertius Bywalec (2,970 p.)
edycja 5 czerwca 2020 przez Hubertius

Tak racja, zrobiłem tak jak wyżej wspomniałeś. De facto przeszło mi już przez wszystkie testy funkcyjne. Ale i tak jeszcze mi się gdzieś czepia na operacjach w main().

Poniższy kod w main():

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "functions.h"
int main()
{
    char * buffer = (char *) malloc (sizeof(char ) * 1001 );
    if( buffer == NULL )
    {
        printf("Failed to allocate memory");
        return 8;
    }
    printf("Podaj tekst do przeksztalcenia: ");
    fgets(buffer,1001,stdin);
    *(buffer + 1000) = '\0';
    printf("Podaj liczbe operacji do przeprowadzenia: ");
    int choice;
    if( scanf("%d",&choice)  != 1 )
    {
        free(buffer);
        printf("Incorrect input");
        return 1;
    }
    if( choice < 2 || choice > 4 )
    {
        free(buffer);
        printf("Incorrect input data");
        return 2;
    }
    int * for_choice = (int *) malloc (sizeof(int) * 4  );
    if( for_choice == NULL )
    {
        free( buffer );
        printf("Failed to allocate memory");
        return 8;
    }
    printf("Podaj wybrane operacje: ");
    int i;
    char * (*first)(const char *);
    char * (*second)(const char *);
    char * (*third)(const char *);
    char * (*forth)(const char *);
    for(i = 0; i < choice; i++)
    {
        if( scanf("%d", for_choice + i )  != 1 )
        {
            free( buffer );
            free ( for_choice );
            printf("Incorrect input");
            return 1;
        }
        if( *(for_choice + i) < 0 ||  *(for_choice + i) > 3 )
        {
            free( buffer );
            free ( for_choice );
            printf("Incorrect input data");
            return 2;
        }
        if( i == 0 )
        {
             if( *(for_choice + i) == 0   )
             {
                 first = lower_to_upper;
             }
             if( *(for_choice + i) == 1 )
             {
                 first = upper_to_lower;
             }
             if( *(for_choice + i) == 2 )
             {
                 first = reverse_letter;
             }
             if( *(for_choice + i) == 3 )
             {
                 first = space_to_dash;
             }
        }
        if( i == 1 )
        {
             if( *(for_choice + i) == 0   )
             {
                 second = lower_to_upper;
             }
             if( *(for_choice + i) == 1 )
             {
                 second = upper_to_lower;
             }
             if( *(for_choice + i) == 2 )
             {
                 second = reverse_letter;
             }
             if( *(for_choice + i) == 3 )
             {
                 second = space_to_dash;
             }
        }
        if( i == 2 )
        {
             if( *(for_choice + i) == 0   )
             {
                 third = lower_to_upper;
             }
             if( *(for_choice + i) == 1 )
             {
                 third = upper_to_lower;
             }
             if( *(for_choice + i) == 2 )
             {
                 third = reverse_letter;
             }
             if( *(for_choice + i) == 3 )
             {
                 third = space_to_dash;
             }
        }
        if( i == 3 )
        {
             if( *(for_choice + i) == 0   )
             {
                 forth = lower_to_upper;
             }
             if( *(for_choice + i) == 1 )
             {
                 forth = upper_to_lower;
             }
             if( *(for_choice + i) == 2 )
             {
                 forth = reverse_letter;
             }
             if( *(for_choice + i) == 3 )
             {
                 forth = space_to_dash;
             }
        }
    }
    char ** for_pointers = (char **) malloc ( sizeof(char *) * (choice + 1)   );
    if( for_pointers == NULL )
    {
        free(buffer);
        free (for_choice);
        printf("Failed to allocate memory");
        return 8;
    }
    for(i = 2; i <= 4; i++)
    {
        if( i == 2 )
        {
            for_pointers = text_modifier(buffer,i, first, second);
        }
        if( i == 3 )
        {
            for_pointers = text_modifier(buffer,i, first, second, third);
        }
        if( i == 4 )
        {
            for_pointers = text_modifier(buffer,i, first, second, third,  forth);
        }
    }
    if( for_pointers == NULL )
    {
        free(for_choice);
        free(buffer);
        printf("Failed to allocate memory");
        return 8;
    }
    for(i = 0; i < choice; i++)
    {
        printf("%s",*(for_pointers + i));
    }
    free(buffer);
    free(for_choice);
    free_texts(for_pointers);
    return 0;
}

A tutaj jeszcze mała aktualizacja funkcji z functions.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "functions.h"

char **text_modifier(const char *text, int how_many, ...)
{
    if( text == NULL || how_many <= 0 )
    {
        return NULL;
    }
    char ** result = (char **) calloc(  (how_many + 1)  ,sizeof(char *)  );
    if( result == NULL )
    {
        return NULL;
    }
    int i = 0;
    va_list list_1;
    va_start(list_1,how_many);
    char * (*pointer_on)(const char *);
    for(i = 0; i < how_many; i++)
    {
        pointer_on = va_arg(list_1, char * (*)(const char *));
        *(result + i) = pointer_on(text);
        if( *(result + i) == NULL )
        {
            va_end(list_1);
            int j = 0;
            while( *(result + j) != NULL  )
            {
                free( *(result + j) );
                j++;
            }
            free(result);
            return NULL;
        }
    }
    va_end(list_1);
    return result;
}
char* lower_to_upper(const char *in)
{
    if( in == NULL )
    {
        return NULL;
    }
    int sizeof_for_buffer= (strlen(in) + 1);
    char * score = (char *) malloc(sizeof(char) *sizeof_for_buffer);
    if( score == NULL )
    {
        return NULL;
    }
    int i = 0;
    while( *(in + i) != '\0' )
    {
        if( *(in + i)>= 97 && *(in + i) <= 122  )
        {
            *(score + i) = *(in + i) - 32;
        }
        else
        {
            *(score + i) = *(in + i) ;
        }
        i++;
    }
    *(score + i) = '\0';
    return score;

}

char* upper_to_lower(const char *in)
{
    if( in == NULL )
    {
        return NULL;
    }
    int sizeof_for_buffer= (strlen(in) + 1);
    char * score = (char *) malloc(sizeof(char) *sizeof_for_buffer);
    if( score == NULL )
    {
        return NULL;
    }
    int i = 0;
    while( *(in + i) != '\0' )
    {
        if( *(in + i) >= 65 && *(in + i) <= 90  )
        {
            *(score + i) = *(in + i) + 32;
        }
        else
        {
            *(score + i) = *(in + i) ;
        }
        i++;
    }
    *(score + i) = '\0';
    return score;
}
char* space_to_dash(const char *in)
{
    if( in == NULL )
    {
        return NULL;
    }
    int sizeof_for_buffer= (strlen(in) + 1);
    char * score = (char *) malloc(sizeof(char) *sizeof_for_buffer);
    if( score == NULL )
    {
        return NULL;
    }
    int i = 0;
    while( *(in + i) != '\0' )
    {
        if( *(in + i) == ' '  )
        {
            *(score + i) = '_';
        }
        else
        {
            *(score + i) = *(in + i);
        }
        i++;
    }
    *(score + i) = '\0';
    return score;
}
char* reverse_letter(const char *in)
{
    if( in == NULL )
    {
        return NULL;
    }
    int sizeof_for_buffer= (strlen(in) + 1);
    char * score = (char *) malloc(sizeof(char) *sizeof_for_buffer);
    if( score == NULL )
    {
        return NULL;
    }
    int i = 0;
    while( *(in + i) != '\0'  )
    {
        if( *(in + i) >= 65 &&  *(in + i) <= 90 )
        {
            *(score + i) = 65 - *(in + i) + 90;
        }
        else if( *(in + i) >= 97 &&  *(in + i) <= 122 )
        {
            *(score + i) = 97 - *(in + i) + 122;
        }
        else
        {
            *(score + i) = *(in + i);
        }
        i++;
    }
    *(score + i) = '\0';
    return score;
}

void free_texts(char ** table_of_texts)
{
    if( table_of_texts == NULL )
    {

    }
    else
    {
        int i = 0;
        while( *(table_of_texts + i) != NULL  )
        {
            free( *(table_of_texts + i) );
            i++;
        }
        free(table_of_texts);
    }

}

Teraz wskazuje mi, że mam wyciek pamięci w przypadku, gdy for_pointers == NULL (ale to dla drugiego już if-a, gdy po przypisaniu wyniku z funkcji text_modifier sprawdzam czy nie doszło do jakiegoś błędu). Nie mam pojęcia co jest grane, mam wrażenie że wszystko co mogłem już w main() dawno zwolniłem jeżeli mowa o wcześniejszych alokacjach.

1
komentarz 5 czerwca 2020 przez overcq Pasjonat (21,710 p.)
for_pointers przydzielasz na zewnątrz funkcji text_modifier i wewnątrz. Poza tym wywołujesz funkcję text_modifier w pętli niepotrzebnie dla wszystkich przypadków podania argumentów pomiedzy 2 a 4, podczas gdy użytkownik podaje tylko jedną wartość, i gubisz tak alokowane for_pointers.

Podobne pytania

0 głosów
2 odpowiedzi 1,079 wizyt
pytanie zadane 24 stycznia 2017 w C i C++ przez spvce Początkujący (260 p.)
0 głosów
1 odpowiedź 264 wizyt
pytanie zadane 3 stycznia 2018 w C i C++ przez lambdag Obywatel (1,310 p.)
0 głosów
1 odpowiedź 148 wizyt
pytanie zadane 1 grudnia 2019 w C i C++ przez Aleksandra01 Użytkownik (530 p.)

92,576 zapytań

141,426 odpowiedzi

319,652 komentarzy

61,961 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...