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

C - funkcja zwracająca wskaźnik na char

Object Storage Arubacloud
0 głosów
4,461 wizyt
pytanie zadane 4 kwietnia 2016 w C i C++ przez esp0x309 Użytkownik (510 p.)

Cześć,

Posiadam pewną funkcję, która usuwa m.in. powtarzające się litery w łańcuchu znaków i zwraca wskaźnik na char. Przykładowo do funkcji przekazuję łańcuch znaków: "kajak". Gdy w funkcji bezpośrednio przed return wyświetlę printf-em wynik to jest ok, wyświetla mi "kaj", ale w main() po wywołaniu funkcji i wyświetleniu wyniku w ten sam sposób pojawia się "ka" ... brakuje ostatniego znaku. Orientuje się ktoś jak rozwiązać problem?


char *usunPowtorzenia(char *tablica)
{
    // tutaj wykonuje operacje usunięcia powtórzeń
    
    printf("%s", tablica); // tutaj wyświetla mi prawidłowy wynik: "kaj"
    return tablica;
}

int main(int argc, char *argv[])
{
    char string[255] = "kajak";
    char *wsk;

    wsk = usunPowtorzenia(string);
    printf("%s", wsk); // tutaj wyświetla "ka" a powinno być "kaj"
}

 

4 odpowiedzi

+1 głos
odpowiedź 6 kwietnia 2016 przez maly Nałogowiec (37,190 p.)
wybrane 1 czerwca 2016 przez esp0x309
 
Najlepsza

Najpoważniejszy błąd, zwracasz wskaźnik na zmienną lokalną która po wyjściu z funkcji zostaje usunięta.

char tmp[255] = { };

tablicaZnakow = tmp;
return tablicaZnakow;

Za daleko iterujesz pętlą for.

for (int i = 0; i <= strlen(tablicaZnakow); i++) // pętla po elementach tablicy >tablicaZnakow<

Pozatym algorytm jest dziwnie zakręcony.

powtarzaj dla całej długości tekstu
	znak = tekst[i]
	jeśli w nowym tekście nie występuje znak dodaj go

 

+1 głos
odpowiedź 4 kwietnia 2016 przez Dorion300 Szeryf (90,250 p.)
Niestety ale posiadam mało informacji by ocenić twój problem. Gdy wrzuciłem twój kod do kompilatora wszystko ładnie działa. Może zadam ci kilka pytań: 1. Jaki masz kompilator? którą ma wersję? 2. Czy rzeczywiście skompilowałeś? czasami można zapomnieć że najpierw się buduje potem się uruchamia, przez co uruchamia się program ale się go nie kompiluje po zmianach wprowadzonych. 3. Jesteś pewny że prawidłowo przepisałeś/skopiowałeś kod?
komentarz 5 kwietnia 2016 przez esp0x309 Użytkownik (510 p.)
1.Posiadam gcc w wersji "gcc (Ubuntu 5.2.1-22ubuntu2) 5.2.1 20151010"

2. Kompiluje i uruchamiam kod w KDevelop, wybrałem opcję "Build" a następnie "Run" ale niestety nadal ten sam problem.

3. Pełny kod podałem w jednym ze swoich komentarzy na odpowiedź.
+1 głos
odpowiedź 4 kwietnia 2016 przez Patrycjerz Mędrzec (192,320 p.)

Samego rozwiązania problemu nie widzę (może podałeś za mało kodu), ale mam dwie sugestie:

  1. Inicjuj tablicę takim zapisem:
    char string[] = "kajak";

    Spowoduje to lepsze zagospodarowanie pamięci

  2. Używając tablicy, korzystasz z jej adresu, czyli pracujesz na oryginalnych danych, więc niepotrzebnie zwracasz adres w funkcji

komentarz 5 kwietnia 2016 przez esp0x309 Użytkownik (510 p.)

Tak myślałem, że może być za mało kodu. Poniżej znajduje się cały kod który generuje "problem". Generalnie jest tu parę rzeczy wykonywanych. Opiszę je krótko. Dodam jeszcze tylko to, że kod który znajduje się w funkcjach wcześniej nie był w funkcjach tylko w main() i działał w porządku. Parę razy będę używał tych funkcji więc chciałem zaoszczędzić sobie pisania i upakować to w funkcje.

1. Do tego przykładowego łańcucha znaków "kajak" doklejany jest łańcuch znaków "abcdefghiklmnopqrstuvwxyz" za pomocą funkcji strcat().

2. Zamieniam litery 'J' na 'I'

3. Usuwam spacje i powtórzenia liter

4. Zwracam returnem wynik

Kod kompiluję na linuxie korzystając z KDevelop

char *zamienJNaI(char *tablicaZnakow)
{
	int i = 0;
	while (tablicaZnakow[i] != 0) 
	 {
        if (tablicaZnakow[i] == 'j')
        tablicaZnakow[i] = 'i';
        i++;
	}
	return tablicaZnakow;
}
// funkcja usuwa powtórzenia, spacje  w stringu 
char *usunPowtorzeniaWStringu(char *tablicaZnakow)
{
	
	char alfabet[] = "abcdefghiklmnopqrstuvwxyz";
	strcat(tablicaZnakow, alfabet);
	
	tablicaZnakow = zamienJNaI(tablicaZnakow); //  zamiana J na I
	printf("%s\n", tablicaZnakow);
	
	int n = 0; // aktualna pozycja do przypisania znaku z tablicy >tablicaZnakow< do >tmp<
	int count; // licznik powtórzeń
	
	char tmp[255] = { };
	
	for (int i = 0; i <= strlen(tablicaZnakow); i++) // pętla po elementach tablicy >tablicaZnakow<
	{
		count = 0; // na początku zerujemy licznik powtórzeń bo ich nie ma
		for (int j = 0; j < 255; j++) // pętla po elementach tablicy >tmp<
		{
			
			if (tablicaZnakow[i] ==  ' ')         //  jeżeli obecny znak to odstęp (spacja) to go omiń 
			{								
				break;			                  // i wyjdź z pętli
			}
			if (tmp[j] == tablicaZnakow[i])       // jeżeli aktualny znak z tablicy >tablicaZnakow< jest w tablicy >tmp<
			{
				count++;                          // to zwiększ licznik o jeden
				if (count > 1)					  // jeżeli licznik count > 1 to nie ma sensu dalej sprawdzać
					break;                        // bo ten znak już jest w >tmp< --> wychodzimy z pętli
			}
		}
		if ((count < 1) && (tablicaZnakow[i] !=  ' '))	// jeżeli licznik jest mniejszy od 1 i tablica[i] != ' ' to znaczy, że nie ma powtórzeń
		{		
			tmp[n++] = tablicaZnakow[i];    // i możemy podstawić znak z >tablicaZnakow< do >tmp<
											// znak w tmp[n] już mamy, dlatego trzeba zainkrementować n
		}									// aby w kolejnej pętli móc podstawić kolejny znak z klucza w kolejnym elemencie kluczaBezPowtorzen
	}
	n++;
	tmp[n] = '\0';
	tablicaZnakow = tmp;
	
	printf("%s",tablicaZnakow);
	return tablicaZnakow;	
}

int main(int argc, char *argv[])
{
	char klucz[255] = "kajak";
	char *wsk;
	
	wsk = usunPowtorzeniaWStringu(klucz);
	
	printf("\n%s ", wsk);
    return 0;
}

komentarz 5 kwietnia 2016 przez mbabane Szeryf (79,280 p.)
co to w ogole za kod? bo on nie dziala tak jak piszesz w pytaniu. To w sumie co chcesz uzyskac bo tu jest zupelnie cos innego wykonywane
0 głosów
odpowiedź 5 kwietnia 2016 przez mbabane Szeryf (79,280 p.)

do typu char* powinno sie chyba tez dodawac znak konca stringa tj. '\0'.

komentarz 5 kwietnia 2016 przez esp0x309 Użytkownik (510 p.)
Dziękuję za odpowiedź. Dopisałem dodanie znaku '\0' po wykonywanych w funkcji operacjach. Niestety to nie pomogło. W dalszym ciągu ostatni znak jest pomijany.

Podobne pytania

0 głosów
2 odpowiedzi 436 wizyt
0 głosów
2 odpowiedzi 787 wizyt
pytanie zadane 9 lutego 2017 w C i C++ przez robRoy Użytkownik (970 p.)
0 głosów
0 odpowiedzi 550 wizyt
pytanie zadane 20 maja 2020 w C i C++ przez fortuna Początkujący (310 p.)

92,566 zapytań

141,420 odpowiedzi

319,614 komentarzy

61,952 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!

...