c'è naturalmente più di un modo di farlo.
uno è usare strtok, che però puoi usare se la stringa non è un "literal" ovvero se in generale il buffer è modificabile, come specificato nella sezione Bugs del man.
In pratica la funzione è utile per estrarre dei "token" (le parole), dati dei separatori; per l'uso, cfr. sempre il man e nota che la stringa "delim" è un elenco di caratteri che consideri delimitatori; nel tuo caso, punteggiatura e spazi (spazio, tab), cioè gli passi una cosa del tipo " \t,;.:-!?" (tutti i caratteri per cui !isalpha) e qualunque altra cosa non può far parte di una "parola". Naturalmente se nel processo di estrazione un token ha lunghezza nulla, passi al successivo.
Poiché il riferimento a isalpha mi fa pensare a un esercizio diverso, quello che probabilmente devi fare è un semplice loop che scorre la stringa iniziale e memorizza ad ogni "separatore" la parola, qualcosa come (consideralo più pseudocodice che C):
for (i = 0, collecting = false, j = 0; i < strlen(s); i++) {
if (!collecting && !isalpha(s[i])) continue;
if ( isalpha(s[i]) ) { collecting = true; parola[j] = append( s[i], parola[j] ); }
else if (collecting && !isalpha(s[i])) { collecting = false; j++; }
// l'else if dovrebbe essere ridondante, ma male non dovrebbe fare....
}
alla fine j è il numero di parole trovate. Si tratta di una specie di macchina a stati. La funzione append "aggiunge" un carattere in fondo alla stringa puntata da parola[j]; la puoi fare anche intelligente nel senso che il buffer può essere creato ad hoc, p.es. in modo un po' grossolano:
char *parola[N] = NULL;
char *append(char c, char *p)
{
if (!p) { p = calloc(1, 2); if (!p) return NULL; p[0] = c; return p; }
size_t l = strlen(p);
char *r = realloc(p, l+2); // if (!r) { ...? ...}
r[l] = c; r[l+1] = 0;
return r;
}
se per la fretta non ho fatto erroracci... (nota che usare realloc per incrementare ogni volta di 1 carattere non è una idea brillante)
poi naturalmente dovrai fare tante free quante sono le "parole" inserite.