Operacje na wskaźnikach

Odpowiedz Nowy wątek
2011-07-10 14:33
spragniony_wiedzy
0

Cześć, chciałem napisać prostą funkcje która wyszukuje konkretne słowo w zdaniu:

char  szukaj(char *zdanie)
{
 
   char *wsk , tab[20];
 
  int i;
      wsk = strstr(buff,"Ala") + strlen("Ala");
 
      i = 0;
 
      while(strncmp(" ", wsk, 1))
      {
    tab[i] = *wsk;
    i++;
    wsk++;
      }
      tab[i] = '\0';
 
return tab;
}
 

Co musi zwracać ta funkcja żeby zadziałało cos takiego, kompilator cały czas wyrzuca błąd ,że znaleziono jest typu int, jak więc zamienić to na typ char, proszę o pomoc i o wyrozumiałość :D, dopiero zaczynam przygodę z C

void main()
{
char *zdanie=" Cos tam cos Ala ma kota " ;
char znaleziono = szukaj(zdanie);
printf("Szukane słowo to : %s", znaleziono");
 
}

Pozostało 580 znaków

2011-07-10 14:40
0

Pierwsze co: znaleziono jest typu char, a nie char*, więc nie możesz zwrócić tablicy do jednego znaku.


<error>There was an error during loading user signature. Please try to reboot the Universe and check again.</error>
edytowany 1x, ostatnio: xeo545x39, 2011-07-10 14:40

Pozostało 580 znaków

2011-07-10 22:03
Kumashiro
0
spragniony_wiedzy napisał(a)
 
char  szukaj(char *zdanie)
{

char *wsk , tab[20];

int i;
wsk = strstr(buff,"Ala") + strlen("Ala");


Co to jest "buff"? Gdzie masz deklarację tego? :D

 > ##### spragniony_wiedzy napisał(a)
> 
```c
while(strncmp(" ", wsk, 1))

Jeśli strstr() zwróci Ci NULL (jak nie znalazł "Ala" w buff), dostaniesz w tym miejscu SEGFAULT.
Dodatkowo, jeśli "Ala" wystąpi na końcu buff, następnym znakiem będzie bajt zerowy, wynikiem strncmp() będzie 1 i - niespodzianka - będziesz sobie radośnie iterował po pamięci za buff (albo dostaniesz SEGFAULT).

spragniony_wiedzy napisał(a)
{
tab[i] = *wsk;
i++;
wsk++;
}
tab[i] = '\0';

A tu kolejny kwiatek. Zupełnie ignorujesz fakt, że tab ma ograniczoną wielkość. Jesli w buff będziesz miał "Ala<dużo spacji, więcej niż 16>", to wyjedziesz z tymi przypisaniami poza tablicę tab i - kolejna niespodzianka - będziesz nadpisywał nie to co trzeba, albo dostaniesz SEGFAULT.

Jak dla mnie to ten kod jest generatorem SEGFAULTów. Napisałeś, że dopiero się uczysz, zatem kilka rzeczy, o których powinieneś wiedzieć:

  1. Z arytmetyką na wskaźnikach trzeba BARDZO uważać i ostrożnie projektować algorytmy. Kompilator nawet się nie zająknie jeśli nie będziesz się pilnował, a o błędach dowiesz się dopiero po uruchomieniu programu, często tylko po zaistnieniu specyficznych warunków (np. w przypadku Twojego kodu jeśli będziesz przeszukiwał cstringa kończącego się na "Ala", lub zawierającego za tym słowem dużą ilość spacji).
  2. Niezależnie od tego czy czytasz, czy piszesz do tablicy, pilnuj żebyś nie wyjechał poza jej wielkość. To podstawa! Pamiętaj, że wskaźnik nie przenosi informacji o rozmiarze obszaru pamięci, na który wskazuje, a funkcja strlen() "wie" jaki rozmiar ma cstring tylko dlatego, że cstring kończy się bajtem zerowym. Jak się nie kończy, to masz problem.
  3. Nigdy nie ufaj danym z zewnątrz, a w szczególności nie zakładaj, że przekazany cstring nie będzie dłuższy niż X. To standardowy błąd początkujących... "przecież nikt nie wpisze imienia dłuższego niż 64 znaki"
  4. Czytaj uważnie dokumentację funkcji, które używasz. Zwracaj szczególną uwagę na wartości przez nie zwracane i odpowiednio je obsługuj. Jeśli funkcja zwraca wskaźnik, musisz założyć, że może zwrócić NULL i być na to przygotowanym.

Pozostało 580 znaków

2011-07-10 22:23
Kumashiro
0
Kumashiro napisał(a)

A tu kolejny kwiatek. Zupełnie ignorujesz fakt, że tab ma ograniczoną wielkość. Jesli w buff będziesz miał "Ala<dużo spacji, więcej niż 16>", to wyjedziesz z tymi przypisaniami poza tablicę tab i - kolejna niespodzianka - będziesz nadpisywał nie to co trzeba, albo dostaniesz SEGFAULT.

Tfu... nie "spacji" tylko "tabulacji" (ASCII code 9).

Jeszcze jedno. Chcesz szukać wyrazów, a szukasz ciągu znaków. Twój kod zadziała źle w przypadku, gdy buff będzie zawierał wyraz np. "zapierdAla". Zainteresuj się funkcją strtok(), albo weź pod uwagę, że szukany ciąg znaków powinien być na początku buff, lub być poprzedzony spacją.

Pozostało 580 znaków

2011-07-11 12:46
spragniony_wiedzy
0

ok uporałem się z tym wyszukiwaniem wyrazów, dzięki za pomoc. Tylko teraz tak :
mam zmienną

 char tab[20]

w której przechowuję znaleziony wyraz będzie to nazwa zażądanego do otwarcia pliku i teraz chce zrobić z nią coś takiego :

filefd = open( tab, O_RDONLY) 

Następnie korzystam z funkcji read(), program się kompiluje ale po uruchomieniu w zmiennej errno pojawia się komunikat " Bad file descriptor"

W czym teraz jest problem ?

Pozostało 580 znaków

2011-07-11 13:23
Kumashiro
0

Brak obsługi błędów. Skąd wiesz czy deskryptor został otwarty? Jeśli jest błąd otwarcia pliku, to wynikiem open() jest -1. Jak to podasz funkcji read() jako deskryptor, to dostaniesz taki błąd. Nie zaniedbuj obsługi błędów!

Pozostało 580 znaków

2011-07-11 13:26
Kumashiro
0

Dobra... masz tu przykładowy kod z obsługą błędów:

/* ... */
 
if ( (fildes = open(path, O_RDONLY)) == -1 ) {
    perror("open()");
    return 1;
};
 
/* ... */

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0