problem z implementacja funkcji strtok

0

Witam :) potrzebuje rady, czy daloby sie jakos uproscic tutaj funkcje strtok? Mam za zadanie zrobic implementacje tej funkcji, jednak ani ona, ani zadna z funkcji pomocniczych nie moga byc dluzsze niz 25 linijek. Dopiero zaczelam uczyc sie programowania i skonczyly mi sie pomysly.


#include<stddef.h>

static int	count_words(const char *str, char c)
{
	int	counter;
	int	idx;
	int	cond;

	counter = 0;
	cond = 0;
	idx = 0;
	while (str[idx])
	{
		if (str[idx] != c && cond == 0)
		{
			cond = 1;
			counter++;
		}
		else if (str[idx] == c)
		{
			cond = 0;
		}
		idx++;
	}
	return (counter);
}

int	wleng(char const *s, char c, int i)
{
	int	wrdleng;
	
	wrdleng = 0;
	while (s[i + wrdleng] != '\0' && s[i + wrdleng] != c)
	{
		wrdleng++;
	}
	return (wrdleng);
}

char	**mallocsen(char const *s, char c)
{
	char	**sent;

	sent = (char **)malloc((count_words(s, c) + 1) * sizeof(*sent));
	if (!sent)
	{
		return (NULL);
	}
	return (sent);
}

char	*mallocword(char const *s, char c, int wrdleng)
{
	char	*wordx;

	wordx = (char *)malloc((wrdleng + 1) * sizeof(char));
	if (!wordx)
	{
		return (NULL);
	}
	return (wordx);
}

char	**strtok(char const *s, char c)
{
	int	i;
	int	wrdleng;
	int	j;
	int	k;
	char	*word;
	char	**sentence;

	sentence = mallocsen(s, c);
	if (!sentence)
		return (0);
	i = 0;
	j = 0;
	while (s[i] != 0 && c != '\0')
	{
	    while (s[i] == c)
			i++;
		if (s[i] == '\0')
			break ;
		wrdleng = wleng(s, c, i);
		k = 0;
		word = mallocword(s, c, wrdleng);
		if (!word)
			return (0);
		while (k < wrdleng)
		word[k++] = s[i++];
		word[wrdleng] = '\0';
		sentence[j] = word;
		j++;
	}
	sentence[j] = NULL;
	return (sentence);
}


 int        main(void)
 {
     char **arr;
    char *phrase = "    Helleo,Flaevlio\t Wuensche!  ";
    arr = strtok(phrase, 'e');
     printf("%s\n", arr[0]);
     printf("%s\n", arr[1]);
     printf("%s\n", arr[2]);
     printf("%s\n", arr[3]);
     printf("%s\n", arr[4]);
      printf("%s\n", arr[5]);
}
3

Oryginalny strtok smaruje po pamięci, czyli zmienia podany napis wstawiając tam znaki '\0';
Poza tym jak spojrzysz uważnie na swoi kody np:

char	*mallocword(char const *s, char c, int wrdleng)
{
	char	*wordx;

	wordx = (char *)malloc((wrdleng + 1) * sizeof(char));
	if (!wordx)
	{
		return (NULL);
	}
	return (wordx);
}

To zauważysz że kod:

char *mallocword(int wrdleng) { return (char*)malloc((wrdleng+1)); }

robi dokładnie to samo, ni mniej ni więcej, no i masz 1 wiersz zamiast 11.

0
_13th_Dragon napisał(a):

Oryginalny strtok smaruje po pamięci, czyli zmienia podany napis wstawiając tam znaki '\0';

Uprzedziłeś mnie.
Czytanie dokumentacji jest dla ...

1

Bardzo ciekawe zadanie, aby w 25 linijkach zmieścić się z implementacją strtok.
Mi się udało dopiero aż w 26. Zachęcam Koleżankę do nie poddawania się.

char* st( char *str, const char *sep )  {

  static char *strpos = NULL;
  if( str != NULL )  strpos = str;
  if( *strpos == '\0' )  return NULL;

  char *ret = strpos;
  for(;; strpos++ )  {

    for( size_t i = 0;; i++ )  {

       if( sep[i] == '\0' )  {

	    *strpos = '\0';
	    strpos += i;
	    return ret;

       }
       if( strpos[i] == '\0' )  return ret;
       if( strpos[i] != sep[i] )  break;

    }

  }

}

1
char *strtok_(char *str,const char *separator)
{
	static char *saved=NULL;
  	if(str) saved=str;
  	if((!saved)||(!*saved))  return NULL;
  	saved=strstr(str=saved,separator);
  	if(saved)
	{
		*saved=0;
		saved+=strlen(separator);
	}
  	return str;
}
0
ksh napisał(a):

Bardzo ciekawe zadanie, aby w 25 linijkach zmieścić się z implementacją strtok.

Tu chyba chodzi o wydzielanie części kodu do funkcji, gdy będzie za dużo linijek. Pewnie może zaimplementować strtok nawet w 1000 linijek po warunkiem, że będzie on porozbijany na małe funkcje.

3

Dziwne, że nikt nie wspominał, że własna definicja strtok narusza "Zasadę jednej definicji" (One Definition Rule), poniweraż w standardowym C istnieje już taka funkcja.
Przez co mogą się dziać naprawdę dziwne rzeczy (widziałem takie rzeczy na SO tyle że z inną funkcją).
Niestaty kompilator i linker nie zgłaszają tego jak błąd.

Dlatego powinieneś zmienić nazwę tej funkcji. Najlepiej jest stosować własny prefix na wszystkie własne globalne symbole.

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