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ć?