There are lots of ways to "break" a C string, more robust, less robust, with or without dynamic allocation, but I'll take exactly what I said:
I tried to use strtok()
, but I was only able to use it to print the separate strings in the terminal
You can also do with strtok
and it's even simpler because some of the work is already done.
Break - Split with array allocated in Stack
Using a two-dimensional array in a stack, you can split it by slightly changing the documentation example :
#include <stdio.h>
#include <string.h>
int qtd_espacos(char *str){
int espacos = 0;
while(*str){
if (*str == ' '){
espacos++;
}
str++;
}
return espacos;
}
int main () {
char str[] = "Bom dia pessoal";
//quebrar - split da string
int qtd_strings = qtd_espacos(str) + 1, i = 0;
char strings[qtd_strings][strlen(str)];
char *pch = strtok (str," ");
while (pch != NULL){
strcpy(strings[i++], pch); //copiar cada string para a posição correta
pch = strtok (NULL, " ");
}
//mostrar cada uma
for (i = 0;i < qtd_strings;++i){
printf("%s\n", strings[i]);
}
//ou seguindo o seu exemplo
printf("%s\n%s\n%s\n", strings[0], strings[1], strings[2]);
return 0;
}
See Ideone
Essentially the only thing I've done the most in relation to documentation is copying each string to the right location via strcpy
.
In order to pre-allocate the right space for the strings, count how many spaces there are to know how many strings will be created. In fact the amount of spaces + 1 may not directly match the number of strings, if there are spaces in a row, but if so, the number of strings will be lower and so it will not make much difference.
At the end of the code, the string has been broken into an array of strings, so in 0
has the first word, in the 1
to the second position, and so on. So its str1
in question equals strings[0]
, str2
a strings[1]
, etc.
Break - Split with array allocated in Heap
To complement it a bit, I also show a way to break using the heap and its malloc
. In many cases this will seem more natural since everything can now be done inside a function and the resulting array of strings can be returned. Since we have the function realloc
, it is also necessary to count the spaces initially, since you can increase the array of strings each time you pick a new one.
Example:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char** split(char *str, int *qtd){
*qtd = 0;
int i = 0;
char **strings = NULL, *pch = strtok (str," ");
while (pch != NULL){
strings = realloc(strings, sizeof(char*) * (*qtd + 1));
strings[i] = malloc(strlen(pch) + 1); // + 1 para o terminador
strcpy(strings[i++], pch);
pch = strtok (NULL, " ");
}
return strings;
}
int main () {
char str[] = "Bom dia pessoal";
int qtd_strings, i;
char **strings = split(str, &qtd_strings); //chamar o split e obter as strings
for (i = 0;i < qtd_strings;++i){
printf("%s\n", strings[i]);
}
//mostrar cada uma
for (i = 0;i < qtd_strings;++i){
printf("%s\n", strings[i]);
}
//ou seguindo o seu exemplo
printf("%s\n%s\n%s\n", strings[0], strings[1], strings[2]);
return 0;
}
See also in Ideone
Notice that the break function receives a pointer to an integer called qtd
. This is because you need to know how many strings were created in split
, otherwise we can not use them. And since the return of the array of strings already exists then the quantity could not be returned and the function changes the value of that pointer directly.
In this version, whenever you no longer need the strings, you should release them using free
, otherwise you may have memory leaks.