First of all, as you already have the notion of vector, you know that placing multiple character vectors(strings) is tiring. So I advise using an array:
int main()
{
char minhas_palavras[10][100];
return 0;
}
With this, I can store 10 words of at most 100 characters each. It has a more efficient way, through pointers and dynamic memory allocation, but for this problem we do not need it.
To receive random numbers, you can use the Rand() function of the library and then play the first matrix input. For example:
int main()
{
const int QUANTIDADE_PALAVRAS = 10;
char minhas_palavras[QUANTIDADE_PALAVRAS][100];
int numero_aleatorio;
/* Aqui voce define suas palavras */
numero_aleatorio = rand() % QUANTIDADE_PALAVRAS;
printf("Palavra escolhida: %s", minhas_palavras[numero_aleatorio]);
return 0;
}
Where we use a constant called QUANTIDADE_PALAVRAS which indicates that in this case the maximum value is 10 and does not vary.
If you want to use pointers and have a better memory utilization to not leave 87 characters empty in the case of "Hello World!". So the code below exemplifies this idea:
void grava_palavra(char *str, const char *palavra);
/* Pega todos os caracteres de *palavra e grava em *str
assim como feito pela função strcopy */
char *aloca_memoria(int quantidade);
/* Essa funcao recebe um inteiro como argumento e retorna
um ponteiro para caracter que indica onde foi alocada a memoria*/
int main()
{
char *palavra;
int quantidade_carac_palavra;
/* Aqui voce define o tamanho da sua palavra. Ex: 13
Não se esqueca do caracter '\0' no final */
palavra = aloca_memoria(quantidade_carac_palavra);
grava_palavra(palavra, "Hello World!");
printf("%s", palavra);
free(palavra);
return 0;
}
So in a similar way it works to place random numbers and get random phrases.
EDIT:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
char *grava(const char *str)
{
char *pont;
int i, tamanho = 0;
while(*(str+tamanho) != '\0')
tamanho++;
pont = (char *)malloc((tamanho+1)*sizeof(char));
for(i=0; i<tamanho+1; i++)
*(pont+i) = *(str+i);
return pont;
}
char **grava_matriz(int quantidade)
{
return (char **) malloc(quantidade*sizeof(char*));
}
int main()
{
char **mat;
int ale, q = 2;
mat = grava_matriz(q);
*(mat) = grava("Hello");
*(mat+1) = grava("hey");
srand((unsigned)time(NULL));
ale = rand()%q;
printf("%s\n", *(mat+ale));
free(*(mat));
free(*(mat+1));
free(mat);
return 0;
}
Great! I understood the first code passed, and so I used the function
strcpy
for each word of each matrix row. Ex:strcpy(minhas_palavras[0],"A vida e bela");
 strcpy(minhas_palavras[1],"Hello World!");
etc....– Misael
For the second piece of code, where you suggest the use of pointers, even with your explanation, I still do not understand the use of the two functions declared before the main function. Still, I see that according to the code snippet presented, if I wanted to use multiple words (matrix), this should be done using the function
malloc
, for example, to allocate these matrices, right?– Misael
char *grava(const char *str){
 char *pont;
 int i, tamanho = 0;
 while(*(str+tamanho) != '\0'){
 tamanho++; }
 pont = (char *)malloc((tamanho+1)*sizeof(char));
 for(i=0; i<tamanho+1; i++){
 *(pont+i) = *(str+i);
 return pont;
 }

 char **grava_matriz(int quantidade){
 return (char **) malloc(quantidade*sizeof(char*));
 }

int main(){
 char **mat;
 int ale, q = 2;
 *(mat) = grava("Hello");
 *(mat+1) = grava("hey");
 ale = rand()%q;
 printf("%s\n", *(mat+ale));
}
– Carlos Adir
You use the same idea as the code, however, using pointers. Yes, the part of making memory allocation is using malloc(or calloc). Above has two functions, the "write" that takes a string and allocates memory and already writes the string to the allocated memory. Na main has an example that takes two words and prints on the screen either the word "hey" or the word "Hello". Copy and ident the code, I tried to put as if it was a code with identation but could not. .
– Carlos Adir
A correction: 1) The Return of the save function is outside the for. 2) After variable declaration, "mat = grava_matrix(q);" 3) Release memory.
– Carlos Adir
Whoa, I got it a little bit more now. It’s just a shame that my pointer skills are not yet well-tuned, because still, I was left with doubt about what is happening in the
while(*(str+tamanho) != '\0')
and in the stretchfor(i=0; i<tamanho+1; i++)
 *(pont+i) = *(str+i);
. And one last question, for each new string created, I must use the commandfree(*(mat+n));
n corresponds to one of the line of the string, to release each string created, one by one?– Misael
Come on. You understand vectors, so you’re halfway to understanding pointers. What happens when you want to pick up a certain vector element? You do
vetor[1]
for example. But what happens if you do*(vetor+1)
? It means the same thing in this case. An array can be understood as a pointer, but unlike the pointer, you cannot change the vector address, i.e., dovetor1 = vetor2
. The compiler will report the error because you are working with vector and not pointers.– Carlos Adir
In the same way it happens with pointers, you actually have a difficulty because you can’t do
ponteiro[1]
to mean*(ponteiro+1)
. So you can play*(ponteiro+1)
asponteiro[1]
, but they are different things for the computer. Now as for thewhile
, The size variable starts at 0 and increments until you find the character'\0'
. Once it finds, it closes the loop. If an empty string is passed, this is,""
, one has to*(str+0)
will have the value of'\0'
and so it closes. That while is just to measure the word size. If it is "love", then size = 4– Carlos Adir
Then, once we know the word size, we should copy it to another. If they were normal vectors, we could just do
pont[i] = str[i]
, but howpont
is a pointer andstr
is a pointer, so I use*(pont+i) = *(str+i)
to copy instead ofpont[i]
. As for the string created, it is always necessary to free the memory withfree
, to learn more about thefree
and other functions of dynamic memory allocation, I advise researching as it is a rather extensive subject for me to explain here.– Carlos Adir
Blz, it’s been explained! Usually, especially for beginners it is difficult to understand pointers, especially when you have a pointer pointing to another pointer. So, about the
free(*(mat));
andfree(*(mat+1));
I noticed that the memory release of pointers is being made, one by one, for each created word. As I will have many words, about 30 I think, is it possible to free all using a for? I’ve never trained pointers yet but I think it’s like this:int i, aux;
for (i = 0,aux = 0; i <= q; i++,aux++){
 free(*(mat+aux));
 }
Right? And finallyfree(mat);
– Misael
Yes, that’s right. You can use the for to release a large amount. And just one detail, its stop condition(
i <= q
) is wrong, actually it is(i < q)
for*(mat+q)
is not defined– Carlos Adir
Okay. Thank you so much for your patience and attention in helping me.
– Misael