Torba puna tokena

Implementirati funkciju size_t split_tokens(const char *s, const char *delim, char ***tokens) koja razdvaja nisku s, po razdvajačima iz skupa delim, na tokene koje onda smešta u tokens.

Ulaz

Sa standardnog ulaza se unosi niska $s$ nepoznate dužine. Za nisku delim izabrati " ,." (razmak, zarez, i tačku).

Izlaz

Na standardni izlaz u zasebnim redovima ispisati dobijene tokene.

Primer

Ulaz

 red,,green, blue , ,yellow

Izlaz

red
green
blue
yellow

Rešenje

main.c

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

#define INITIAL_SIZE 8

void free_tokens(char **tokens, size_t num_tokens)
{
	for (size_t i = 0; i < num_tokens; i++) {
		free(tokens[i]);
	}
	free(tokens);
}

ssize_t split_token(const char *s, const char *delim, char ***tokens)
{
	size_t capacity = INITIAL_SIZE;
	*tokens = malloc(capacity * sizeof (char *));
	if (*tokens == NULL) {
		return -1;
	}

	ssize_t num_tokens = 0;

	const char *start = s;
	while (*start != '\0') {
		start += strspn(start, delim);
		if (*start == '\0') {
			break;
		}

		const char *end = start + strcspn(start, delim);
		size_t token_length = end - start;
		char *token = malloc((token_length + 1) * sizeof (char));
		if (token == NULL) {
			free_tokens(*tokens, num_tokens);
			return -1;
		}
		strncpy(token, start, token_length);
		token[token_length] = '\0';
		start = end;

		if (num_tokens >= capacity) {
			capacity *= 2;
			char **new_tokens = realloc(*tokens, capacity * sizeof (char *));
			if (new_tokens == NULL) {
				free(token);
				free_tokens(*tokens, num_tokens);
				return -1;
			}
			*tokens = new_tokens;
		}

		(*tokens)[num_tokens++] = token;
	}

	if (num_tokens < capacity) {
		char **new_tokens = realloc(*tokens, num_tokens * sizeof (char *));
		if (new_tokens != NULL) {
			*tokens = new_tokens;
		}
	}

	return num_tokens;
}

int main(void)
{
	const char *delim = " ,.";

	char *line = NULL;
	size_t len = 0;

	ssize_t nread = getline(&line, &len, stdin);
	if (nread == -1) {
		exit(EXIT_FAILURE);
	}

	char **tokens = NULL;
	size_t num_tokens = split_token(line, delim, &tokens);
	if (num_tokens == -1) {
		free(line);
		exit(EXIT_FAILURE);
	}

	for (size_t i = 0; i < num_tokens; i++) {
		printf("%s\n", tokens[i]);
	}

	free_tokens(tokens, num_tokens);
/*
	// using strtok to tokenize the input line

	char *token = strtok(line, delim);
	while (token != NULL) {
		printf("%s\n", token);
		token = strtok(NULL, delim);
	}
	free(token);
*/

	free(line);

	exit(EXIT_SUCCESS);
}