Solucionado (ver solução)
Solucionado
(ver solução)
5
respostas

Codigo

Senhores, bom dia! Até o final da aula 2, suponhamos que eu use apenas 3 chutes: char chutes[26]; int tentativas = 0;

Não consegui entender o porquê que errando ou acertando as letras, no final é dado o printf da palavra inteira.... -primeiro chute-


Qual letra? A _ _ _ A _ _ _ A

-segundo chute -Qual letra? H_ _ _ A _ _ _ A

-terceiro chute -Qual letra? JM E L A N C I A

5 respostas

Seria interessante colocar um pouco do código que você fez. Provavelmente ele imprime porque foi dito para fazer isso dentro de alguma condição.

Tente ler o seu código e pensar como ele está funcionando. Se puder siga com papel e lápis anotando o que seria o comportamento dele (debug bem simples mesmo).

Abcs

#include <stdio.h>

#include <string.h>

int main() {

char palavrasecreta[20];
sprintf(palavrasecreta, "MELANCIA");

int acertou = 0;
int enforcou = 0;

//char chutes[26]; alterei para 2 chutes
char chutes[2];
int tentativas = 0;

do {

    for(int i = 0; i < strlen(palavrasecreta); i++) {
        int achou = 0;

        for(int j = 0; j < tentativas; j++) {
            if(chutes[j] == palavrasecreta[i]) {
                achou = 1;
                break;
            }
        }

        if(achou) {
            printf("%c ", palavrasecreta[i]);
        } else {
            printf("_ ");
        }
    }
    printf("\n");

    char chute;
    printf("Qual letra? ");
    scanf(" %c", &chute);

    chutes[tentativas] = chute;
    tentativas++;


} while (!acertou && !enforcou);

}

// ele entra para imprimir a palavra secreta se na condição achou. Porem ele nao achou, e mesmo assim imprime ela toda após todos os chutes. (no caso, 3 chutes)

Como uma primeira observação:

Note que o tamanho da nossa string chutes tem apenas duas posições.

Após o segundo chute teremos três tentativas, como vamos inserir o chute em um endereço de array que não existe?

Eu não sou a favor de entregar a resposta para o problema, ao invés disso vou sugerir que você adicione varios printf(valordavariavel); durante o código e analise o valor dela em cada iteração.

Se possível adiciona um scanf(); para que o código pare durtante a execução e você possa ler naquele momento, apertando enter para continuar.

Experimente aumentar a quantidade de chutes e veja se esse comportamento muda.

O ideal seria que o programa parasse quando atingisse o máximo de chutes disponível, não?

;¬)

Compreendi a questão do array. De fato nao dá pra inserir o chute sem endereço. Todavia percebo dois comportamentos diferentes: No dev c++ e no compilador online. DEV C++: no final das tentativas ele muda o valor da variável palavrasecreta ou sobrescreve. No compilador online ele mostra a palavrasecreta toda, porém nao passa em nenhum ponto do código.

solução!

Certo. Pode haver diferenças entre compiladores, no caso usei o GCC do Linux, que é o mesmo do Dev C++, é o compilador GNU, vem no pacote TDM.

Não sei qual compilador a versão online usa, mas pode ter diferentes reações com acesso fora do escopo. Segundo a documentação da linguagem C do ISO, não tem uma reação definida para isso:

"Possible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message)."

"behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements"

Quando você tenta acessar um endereço além do escopo, no melhor cenário vamos ter essas reações malucas, é melhor você não tentar achar um padrão nisso, porque seu programa não foi feito para fazer isso.

Quando acessamos um endereço não reservado previamente, podemos estar acessando o endereço de outro programa. É quase como usar uma varíavel sem zerar ela antes, sabe-se lá o que haverá lá.

Por fim, acho que agora para seu programa ficar completo é só adicionar o mecanismo de enforcar ou de acertar.

A melhor coisa que se faz como desenvolvedor e engenheiro de software é prever que certas coisas podem sair do previsto (como acessar memória além do escopo do array) e proteger o usuário disso.

Desenvolvi para embarcados profissionalmente por alguns anos, isso em um embarcado pode causar problemas sérios, é extremamente necessário criar recursos que previnam o programa de ir para uma região desconhecida da memória.

Espero ter ajudado! =¬)