Funkcja, wskaźnik do tablicy, wyświetlanie

0

Cześć,

zgłupiałem, więc piszę do Was. Nie rozumiem, dlaczego napisany przeze mnie program nie zwraca zawartości zmodyfikowanej przez funkcję tablicy. Generalnie, program ma pobierać n znaków lub kończyć się po wystąpieniu znaku odstępu - ten element działa. Na koniec zmodyfikowaną tablicę chcę wyświetlić poprzez: puts(lancuch). Niestety, wyświetla się puste pole. Dopiero gdy w funkcji głównej main wyświetlę zmodyfikowany lancuch (zakomentowane w programie) pojawia się wynik. Gdzie jest problem?

#include <stdio.h>
#include <ctype.h>

void funkcja(char * lancuch, int ile);

int main(void)
{
  char * slowa;
  funkcja(slowa,3);
  //puts(slowa);

  return 0;
}

void funkcja(char * lancuch, int ile)
{
  fgets(lancuch, ile+1, stdin);

  while(*lancuch)
  {
    if(isspace(*lancuch))
    {
      *lancuch = '\0';
      break;
    }
    lancuch++;
  }

  puts(lancuch);
}
1

dlaczego napisany przeze mnie program nie zwraca zawartości zmodyfikowanej przez funkcję tablicy

A gdzie masz zdefiniowaną tablicę? Z tego to widzę, to przekazujesz do funkcji **fgets **tylko sam niezainicjalizowany wskaźnik.

1

J.w. to w ogóle nie powinno sie uruchomić, chyba, że z seagfaultem.

0

To się uruchamia i DZIAŁA. Gdy wyświetlam (po wykonaniu napisanej funkcji) tablicę w funkcji głównej (main) to wynik jest dokładnie taki, jak założyłem.

0
TomaszLiMoon napisał(a):

dlaczego napisany przeze mnie program nie zwraca zawartości zmodyfikowanej przez funkcję tablicy

A gdzie masz zdefiniowaną tablicę? Z tego to widzę, to przekazujesz do funkcji **fgets **tylko sam niezainicjalizowany wskaźnik.

#include <stdio.h>

int main(void)
{
  //char * slowa;
  char slowa[100];
  
  scanf("%s", slowa);
  printf("%s", slowa);

  return 0;
}

char * slowa jest równoważne z char slowa[100] i w przypadku tego programu również zamiennie można deklarować tablicę.

1

To się uruchamia i DZIAŁA.

Tylko przypadkiem :) Nadpisujesz jakąś losową pamięć i jak masz szczęście i nadpiszesz niewiele, to program nie wybuchnie.

char * slowa jest równoważne z char slowa[100]

Bzdura, jedno alokuje pamięć a drugie ustawia wskaźnik na losowy adres. Spróbuj w tym swoim przypadku z char* wpisać jakis długi string i zobacz co sie stanie.

0

Abstrahując od "działania", podstawowa lektura: Przekazywanie parametru przez wartość i referencję

0

Jak @Shalom zauważył, działa przypadkiem. Powinieneś dostać seagfault już we fgets. Można to naprawić i przy okazji trochę ulepszyć (oddzielna funkcja do wyświetlania tablicy, musi być bo wskaźnik w funkcji Ustawiasz na koniec):

#include <stdio.h>
#include <ctype.h>

void funkcja(char * lancuch, int ile);
void showArray(char * ptr, int sz) {
  for (int i = 0; i < sz; ++i)
    printf("%c", ptr[i]);
}

int main(void)
{
  int size = 3;
  char * slowa = tu trzeba zarezerwować pamięć na size znaków
  funkcja(slowa,size);
  showArray(slowa, size);
  printf("\n");

  return 0;
}

void funkcja(char * lancuch, int ile)
{
  

  fgets(lancuch, ile+1, stdin);
  while(*lancuch)
  {
    if(isspace(*lancuch))
    {
      *lancuch = '\0';
      break;
    }
    lancuch++;
  }

}
0
kq napisał(a):

Abstrahując od "działania", podstawowa lektura: Przekazywanie parametru przez wartość i referencję

Dzięki za podstawową lekturę, lecz nie w tym leży problem. Ja rozumiem przekazywanie wartości przez adres zmiennej (&) oraz jej odczytywanie za pomocą operatora dereferencji.

int x = 10;
int * wsk;
wsk = &x;
*wsk = 20;

I rozumiem, że dzięki powyższemu zapisowi, zmienna x przyjmuje wartość 20 - nie jej kopia, lecz ona sama.

Dzięki za zainteresowanie, będę walczył dalej.

0
lion137 napisał(a):

Jak @Shalom zauważył, działa przypadkiem. Powinieneś dostać seagfault już we fgets. Można to naprawić i przy okazji trochę ulepszyć (oddzielna funkcja do wyświetlania tablicy, musi być bo wskaźnik w funkcji Ustawiasz na koniec):

#include <stdio.h>
#include <ctype.h>

void funkcja(char * lancuch, int ile);
void showArray(char * ptr, int sz) {
  for (int i = 0; i < sz; ++i)
    printf("%c", ptr[i]);
}

int main(void)
{
  int size = 3;
  char * slowa = tu trzeba zarezerwować pamięć na size znaków
  funkcja(slowa,size);
  showArray(slowa, size);
  printf("\n");

  return 0;
}

void funkcja(char * lancuch, int ile)
{
  

  fgets(lancuch, ile+1, stdin);
  while(*lancuch)
  {
    if(isspace(*lancuch))
    {
      *lancuch = '\0';
      break;
    }
    lancuch++;
  }

}

Dziękuję, będę analizował.

0
mtbchn napisał(a):
kq napisał(a):

Abstrahując od "działania", podstawowa lektura: Przekazywanie parametru przez wartość i referencję

Dzięki za podstawową lekturę, lecz nie w tym leży problem. Ja rozumiem przekazywanie wartości przez adres zmiennej (&) oraz jej odczytywanie za pomocą operatora dereferencji.

int x = 10;
int * wsk;
wsk = &x;
*wsk = 20;

I rozumiem, że dzięki powyższemu zapisowi, zmienna x przyjmuje wartość 20 - nie jej kopia, lecz ona sama.

Dzięki za zainteresowanie, będę walczył dalej.

0

Ostateczna, działająca wersja programu wygląda tak:

#include <stdio.h>
#include <string.h>
#include <ctype.h>

void slowo(char * lancuch, int ile);
void wypisz(char * lancuch);

int main(void)
{
  char tablica[100];

  slowo(tablica,10);
  wypisz(tablica);

  return 0;
}

void slowo(char * lancuch, int ile)
{
  fgets(lancuch, ile+1, stdin);

  while(*lancuch)
  {
    if(isspace(*lancuch))
    {
      *lancuch = '\0';
    }
    lancuch++;
  }
  lancuch = 0;
}

void wypisz(char * lancuch)
{
  puts(lancuch);
}

Mam nadzieję, że teraz jest ok. Dziękuję za podpowiedzi.

0

Jeśli zdaje Ci się, że Twój program w C działa, to masz rację. Zdaje Ci się.

C jest pełne tzw Undefined Behaviour (UB). To jest dyplomatyczna nazwa, że programista popełnia błąd, ale jest nieokreślone, czy ten błąd się jakoś widocznie ujawni, czy nie. Może się nie ujawnić w jakiejś sytuacji. Co tutaj zachodzi. Zwłaszcza w środowiskach 16bitowych bez ochrony, a jeszcze nieliczni maniacy tego używają.

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