Problem z czyszczeniem tablicy char

0

Witam.
Dostałem do napisania algorytm na wyszukiwanie wzorca w tekście (naiwny oraz KMP), sam algorytm nie sprawia mi problemu, a bardziej jego dopieszczenie, czyli ograniczenie długości słowa do 50, a wzorca do 10.. Dokładniej chodzi mi o to, że gdy user poda za długie słowo (> 50) to program prosi go o zrobienie tego jeszcze raz - wiadomo while - ale zauważam, że to sprawia jakieś problemy, zmienia mi zawartość tekstu, a potem wzorca.. Wysypuje się...
Tutaj kod:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void algNaiwny(char *tekst, char *wzorzec);
void read(char *tekst, char *wzorzec);

int main()
{
    char *tekst;
    char *wzorzec;
    read(&tekst, &wzorzec);
    algNaiwny(&tekst, &wzorzec);
    return 0;
}

void algNaiwny(char *tekst, char *wzorzec)
{
    int i = 0;
    int m = strlen(tekst);
    int n = strlen(wzorzec);
    while (i < m - n)
    {
        int j = 0;
        while((wzorzec[j] == tekst[i+j]) && (j < n))
              j++;
        if(j == n)
            printf("Indeks: %d\n", i+1);
        i++;
    }
}

void read(char *tekst, char *wzorzec)
{
    printf("Podaj tekst: ");
    scanf("%s", tekst);
    while(strlen(tekst) > 50)
    {
        memset(tekst, '\0', sizeof(char*)*strlen(tekst));
        printf("Podaj jeszcze raz, przekroczyles zakres: \n");
        scanf("%s", tekst);
    }
    printf("Podaj wzorzec: ");
    scanf("%s", wzorzec);
    while(strlen(wzorzec) > 10)
    {
        memset(tekst, '\0', sizeof(char*)*(strlen(wzorzec)));
        printf("Podaj jeszcze raz, przekroczyles zakres: \n");
        scanf("%s", wzorzec);
    }
    printf("\nTekst: %s\n", tekst);
    printf("\nWzorzec: %s", wzorzec);
}

Próbowałem to robić memsetem, ale to nic nie daje.. Już nie mam pomysłów jak to skutecznie załatwić..

Z góry dziękuję za pomoc.

0

Można to zrobić tak: (Nie jest to piękne ani tym bardziej odkrywcze, ale jako tako działa):

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

#define READ_SIZE 10

void algNaiwny(char *tekst, char *wzorzec);
void read(char **tekst,char **wzorzec);
void read_with_alloc(const char *communicate,char **data);

int main()
{
    char *tekst = NULL;
    char *wzorzec = NULL;

   	read(&tekst,&wzorzec);
   	algNaiwny(tekst, wzorzec);

	free(tekst);
	free(wzorzec);
    return 0;
}
 
void algNaiwny(char *tekst, char *wzorzec)
{
    int i = 0;
    int m = strlen(tekst);
    int n = strlen(wzorzec);
    while (i <= m - n)					//zmiana nie szukało ostatniego podciągu czyli teskst: mleko wzorzec: ko
    {
        int j = 0;
        while((wzorzec[j] == tekst[i+j]) && (j < n))
              j++;
        if(j == n)
            printf("\nIndeks: %d", i+1);
        i++;
    }
	printf("\n");
}
 

//read_with_alloc
//wyczysc poprzednie dane, zaalokuj podstawowy rozmiar z defina
//wyswietl komunikat
//realokuj jeśli jest potrzeba i wczytuj po jednym znaku sprawdzajac czy to '\n', aby zakońćzyć
void read_with_alloc(const char *communicate,char **data){		//zaalokuj pamiec dynamicznie
	free(*data);
	*data = (char *)malloc(READ_SIZE * sizeof(char));
	
	printf("%s",communicate);
	int i,j;
	char ch;
	for(i = 1;;++i){
		*data = (char *)realloc(*data,i*READ_SIZE);
		for(j=0;j<READ_SIZE-1;++j){
			if(fread(&ch,1,sizeof(char),stdin)){
				if(ch == '\n'){
					*(*data + (i-1)*(READ_SIZE-1) + j) = 0;
					return;
				}else{
					*(*data + (i-1)*(READ_SIZE-1) + j) = ch;
				}
			}
		}
	}
}

void read(char **tekst, char **wzorzec)
{

	read_with_alloc("Podaj tekst: ",&*tekst);
	read_with_alloc("Podaj wzorzec: ",&*wzorzec);
    
	printf("\nTekst: %s\n", *tekst);
    printf("\nWzorzec: %s", *wzorzec);

}

1

Spójrz tutaj... W funkcji main() tworzysz dwa wskaźniki tekst i wzorzec,
natomiast w funkcjach algNaiwny i read prosisz też o wskaźniki.

int main()
{
    char *tekst;
    char *wzorzec;
    read(&tekst, &wzorzec);
    algNaiwny(&tekst, &wzorzec);
    return 0;
}
 
void algNaiwny(char *tekst, char *wzorzec)

Natomiast Ty podajesz tam adres na ten wskaźnik, a nie sam wskaźnik.
Adres, podawać należy wtedy, gdy utworzysz zwykłą zmienną.

Spróbuj to poprawić i sprawdź czy wtedy zadziała ;)

0

Chwilka.. Bo przyznam, że się pogubiłem.. Gdzie mam coś zmienić, gdzie szukać błędu? W mainie czy funkcjach.

0

Przemyśl to co napisałem ;)
Po prostu na początek spróbuj do obu funkcji podawać nie adresy tych wskaźników, a dosłownie same wskaźniki.
Deklaracja wskaźnika: *wsk
Adres wskaźnika: &wsk
Wartość wskaźnika: wsk
Jeśli funkcja prosi o argument *wsk to należy jej podawać po prostu wskaźnik, a nie adres tego wskaźnika.

0

Gdy w mainie zamieniłem &wzorzec na wzorzec to od razu po wpisaniu "Tekstu" wysypywało.

1

Nigdzie nie alokujesz pamięci. Korzystasz z wskaźników, które nie wiadomo na co pokazują.
Musisz najpierw przydzielić pamięć, statycznie lub dynamicznie.

Do tego:

read(&tekst, &wzorzec);

gdy

    char *tekst;
    char *wzorzec;

a deklaracja read:

void read(char *tekst, char *wzorzec);

Przekazujesz pusty niezainnicjowany niczym wskaźnik, który nie wiadomo na co pokazuje bo jest tworzony na stosie i ma losową wartość, czegoś co było tam wcześniej. Do read przekazujesz adres "&" tego niezainicjowanego wskaźnika co już jest niezgodne z deklaracją funkcji bo masz tam char * zamiast char **.

Czyli, aby poprawić ten program, albo zadeklarujesz tablicę znaków:

char tablica[iles_pojemności];

albo przydzielisz wskaźnikowi pamięć dynamiczną mallociem, 2 post.

I w takim przypadku możesz przekazać sobie tą tablicę do funkcji za pomocą wskaźnika.

Każde tworzenie tablicy statycznej jeśli nie jest to wymagane to zły pomysł prowadzący często do błedów, więc najlepiej skup się na pamięci dynamicznej (malloc/free).

0

musisz przydzielić pamieć inaczej mogiła.

Choćby char buff[200];

Pzdr.

0

Teraz rozumiem, dziękuję.

Natomiast prostszego sposobu do ograniczenia nie ma, tak? Niż ten podany w drugim poście?

0

Moim zdaniem prościej będzie tak:

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

unsigned int get_line(char *str, const unsigned int limit);
void read(char *str, const char *msg, const unsigned int  limit);

int main(int argc, char *argv[]) {

  char *text = malloc((10 + 1) * sizeof(char));

  read(text, "Enter text: ", 10);

  printf("Entered: %s.\n", text);

  free(text);

  return EXIT_SUCCESS;
}

void read(char *str, const char *msg, const unsigned int  limit) {
  do {
    printf("%s", msg);
    fflush(stdout);
  } while (get_line(str, limit) > limit);
}

unsigned int get_line(char *str, const unsigned int limit) {
/* Read characters from stdin until limit have been reached, or CR or LF or EOF, whichever happens first.
 *
 * Return number of characters existed in stdin, without CR or LF.
 */
  char c;
  unsigned int i;
  for (i = 0; i < limit && (c = getchar()) != EOF && c != '\n' && c != '\r'; ++i)
    *str++ = c;

  *str = '\0';

  if (i == limit) {
    /* Flush any character which left in stdin */
#ifdef _WIN32
  while((c = getchar()) != EOF && c != '\n')  //CRLF
    if (c != '\r')
      ++i;
#elif defined __APPLE__
  while((c = getchar()) != EOF && c != '\r')  //CR
    ++i;
#else
  while((c = getchar()) != EOF && c != '\n')  //LF
    ++i;
#endif
  }
  return i;
}

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