Printing of predefined phrases at random in C

Asked

Viewed 1,139 times

0

Hello, I’m a beginner in programming and I’m learning to code in C. I want to do a show that has some sentences already defined. Ex c/ vectors: char vet1[100] = {"Hello World!"}; char vet2[100] = {"segunda frase"}; ... and with each run, return a different phrase on the user screen. The closest I came was thinking about using the enum together with rand();, but it doesn’t work because it returns only a constant with decimal value. I think the solution would involve the use of several vetores ou uma matriz de strings, but I don’t know if that’s right.

Can anyone give me an idea? As long as it’s easy to understand for a beginner.

I have learned basic contents, and also vectors, matrices, functions, pointers, dynamic allocation and files.

NOTE: It is not necessary to pass the entire code, just explain me what is the best solution for implementing the sentence part.

1 answer

3


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 strcpyfor each word of each matrix row. Ex: strcpy(minhas_palavras[0],"A vida e bela");&#xA; strcpy(minhas_palavras[1],"Hello World!");etc....

  • 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?

  • char *grava(const char *str){&#xA; char *pont;&#xA; int i, tamanho = 0;&#xA; while(*(str+tamanho) != '\0'){&#xA; tamanho++; }&#xA; pont = (char *)malloc((tamanho+1)*sizeof(char));&#xA; for(i=0; i<tamanho+1; i++){&#xA; *(pont+i) = *(str+i);&#xA; return pont;&#xA; }&#xA;&#xA; char **grava_matriz(int quantidade){&#xA; return (char **) malloc(quantidade*sizeof(char*));&#xA; }&#xA;&#xA;int main(){&#xA; char **mat;&#xA; int ale, q = 2;&#xA; *(mat) = grava("Hello");&#xA; *(mat+1) = grava("hey");&#xA; ale = rand()%q;&#xA; printf("%s\n", *(mat+ale));&#xA;}

  • 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. .

  • A correction: 1) The Return of the save function is outside the for. 2) After variable declaration, "mat = grava_matrix(q);" 3) Release memory.

  • 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 stretch for(i=0; i<tamanho+1; i++)&#xA; *(pont+i) = *(str+i);. And one last question, for each new string created, I must use the command free(*(mat+n)); n corresponds to one of the line of the string, to release each string created, one by one?

  • 1

    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., do vetor1 = vetor2. The compiler will report the error because you are working with vector and not pointers.

  • 1

    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) as ponteiro[1], but they are different things for the computer. Now as for the while, 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

  • 1

    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 how pont is a pointer and stris a pointer, so I use *(pont+i) = *(str+i) to copy instead of pont[i]. As for the string created, it is always necessary to free the memory with free, to learn more about the free and other functions of dynamic memory allocation, I advise researching as it is a rather extensive subject for me to explain here.

  • 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)); and free(*(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++){&#xA; free(*(mat+aux));&#xA; } Right? And finally free(mat);

  • 1

    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

  • Okay. Thank you so much for your patience and attention in helping me.

Show 7 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.