Ir ao conteúdo

Posts recomendados

Postado
/*Primeira regra: construir o codigo abaixo em C com a funcao fgets e uma funcao propria denominada comprimento(), conforme codificação abaixo;
Segunda regra: esse codigo deve mostrar sempre a resposta "Senha invalida", pois quando voce usa fgets() no final será adicionado o elemento NULL (\0), isso é para acontecer pois o objetivo do código é didático, sobre esse erro de logica, previsto quando você utiliza a função strcmp para achar a senha verdadeira que é "abracadabra" que nunca vai ser validada pelo erro proposital inserido nele;
Terceira regra: ele irah mostrar um comprimento sempre maior que a cadeia de caracter que voce digitar, pois o caracter '\0' é contado também.
Diante das regras acima, como faço para mostrar a cadeia de caracteres capturada pela função fgets(), inclusive o ultimo caracter da cadeia digitada, o NULL ou o caracter '\0', colocado de forma automatica pela função fgets().*/

#include <stdio.h> 
#include <string.h>

/*Funcao que conta o numero de caracteres da string digitada, inclusive o caracter "NULL" inserido automaticamente no final dela*/

int comprimento(char *str) {
        int total=0;
        while( str[total] != '\0')
        total++;
        return total;
}

int main(void) {
    char *str[256];
    printf("Senha? ");
    fgets(str, 256, stdin);
    printf("\nEsta eh a senha que digitei: %s\n",str);
    printf("\nO comprimento da senha digitada eh: %d\n",comprimento(str));
    if( strcmp(str,"abracadabra")==0 ){
        puts("Ok!");
}
    else {
        puts("Senha invalida!");
}
    return 0;
}

/*Primeira regra: construir o codigo abaixo em C com a funcao fgets e uma funcao propria denominada comprimento(), conforme codificação abaixo;
Segunda regra: esse codigo deve mostrar sempre a resposta "Senha invalida", pois quando voce usa fgets() no final será adicionado o elemento NULL (\0), isso é para      acontecer pois o objetivo do código é didático, sobre esse erro de logica, previsto quando você utiliza a função strcmp para achar a senha verdadeira que é "abracadabra"  que nunca vai ser validada pelo erro proposital inserido nele;
Terceira regra: ele irah mostrar um comprimento sempre maior que a cadeia de caracter que voce digitar, pois o caracter '\0' é contado também.
 Diante das regras acima, como faço para mostrar a cadeia de caracteres capturada pela função fgets(), inclusive o ultimo caracter da cadeia digitada, o NULL ou o caracter '\0', colocado de forma automatica pela função fgets().*/

 

#include <stdio.h> 
#include <string.h>

 

/*Funcao que conta o numero de caracteres da string digitada, inclusive o caracter "NULL" inserido automaticamente no final dela*/

 

int comprimento(char *str) {
        int total=0;
        while( str[total] != '\0')
        total++;
        return total;
}

int main(void) {
        char *str[256];
        printf("Senha? ");
        fgets(str, 256, stdin);
        printf("\nEsta eh a senha que digitei: %s\n",str);
        printf("\nO comprimento da senha digitada eh: %d\n",comprimento(str));
        if( strcmp(str,"abracadabra")==0 ){
             puts("Ok!");
}
        else {
             puts("Senha invalida!");
}
       return 0;
}>

Postado

@MscMagoo @MscMagoo    existe vários modos de fazer esse exercício ,  e  creio que houve um equívoco nas informações desse enunciado ,   pois todos os comando que fazem a leitura do teclado adicionam o caractere nulo , null ,  no final da string , e o fgets também faz isso , mas o que ele faz também é adicionar o caractere newline  '\n'  ,  na string  antes do '\0' , pois ele pega também o enter que foi pressionado  , 

após pressionar o botão enter no teclado , o fgets pega tudo que foi digitado , até o enter , 
e adiciona o finalizador de string \0 , e essa string fica assim :

abracadabra\n\0

o   \n ocupa apenas uma posição no vetor de char , que é a string
e o \0 também .

então você pode colocar um loop percorrendo os caracteres da string , e comparar com o '\n'  e '\0'  , e encontrando escreva eles usando duas barras reversas '\\n'   '\\0' .

  • Curtir 1
Postado

@devair1010 Muito Obrigado, Devair, por sua resposta e atenção, vai me ajudar entender melhor a linguagem C, grande abraço.

@devair1010 @devair1010 Devair, só não entendi, por que com a função gets a senha "abracadabra" é achada sem problema e não apresenta a questão do "\n" e "\0" no final da string capturada (aquela que inseri via teclado, como sendo uma provável senha). Obrigado

Postado

@MscMagoo Você pode ler sobre sobre o comportamento da funções gets() e fgets() na documentação.

Chamando fgets(), logo antes do '\0', você vai ter um '\n' se o mesmo for lido. O único caractere garantido de fato no final da string é o '\0':

Citação

fgets reads characters from the current stream position to and including the first newline character, to the end of the stream, or until the number of characters read is equal to numChars - 1, whichever comes first. The result stored in str is appended with a null character. The newline character, if read, is included in the string.

Se a gets() faz isso ou não, acho que não chega a ser tão interessante saber, já que esta é obsoleta e usá-la é uma perda de tempo, mas de qualquer forma, na documentação está escrito:

Citação

The gets function reads a line from the standard input stream stdin and stores it in buffer. The line consists of all characters up to and including the first newline character ('\n'). gets then replaces the newline character with a null character ('\0') before returning the line. In contrast, the fgets function retains the newline character.

 

44 minutos atrás, MscMagoo disse:

só não entendi, por que com a função gets a senha "abracadabra" é achada sem problema e não apresenta a questão do "\n" e "\0" no final da string capturada

Está respondida então a questão do '\n' e do '\0'. Só para complementar:

Citação

Uma "string" é uma sequência contígua de caracteres terminados por e incluindo o primeiro caracter nulo. ANSI/ISO 9899:1990 (O padrão ANSI C), seção 7.1.1

Então se é uma string finalizada com o caractere nulo, gets() e fgets() devem garantir um no final da string.

Postado

Seria bom se tivesse um jeito de você nunca ter lido essas 3 "regras" mas não tem.

 

nonsense. Em 3 regras..

 

strings em C terminam com um zero. É a definição. Pode chamar de NULL, de \0, de '\0' como vejo às vezes, mas é só isso: um byte com zero marca o fim de uma string.

 

Isso quer dizer que todas as funções que trabalham com string (e o  seu programa se quer usar uma) vão colocar um zero ao final da sequência de char. Uma linha como 

    

    const char clube[] = "dois";

 

Vai reservar 5 bytes a partir do endereço que o compilador arrumar para clube. É a definição. clube é  const char[5].

 

E vai colocar os valores, com o zero ao final.

 

No entanto o tamanho da string é 4.  strlen() a cada chamada vai no endereço do argumento, clube no caso, e conta um por um os valores até achar o primeiro zero. É a definição.

 

O problema com fgets()

 

O seu texto com as tais regras está confundindo o que acontece com o zero ao final da string e o ENTER, o tal newline, '\n' que causa o retorno de fgets(). Ou podia ser de fscanf(), scanf(), fread(), fgetc(), qualquer coisa com fluxos --- streams --- de entrada.

 

fgets() é
 

    char *fgets(char *str, int n, FILE *stream)

 

E fgets() retorna um ponteiro para char, uma string, então por definição terminado por zero. Só que fgets() lê no máximo n caracteres. Pode ler menos, nunca mais. 

 

Na configuração normal no Windows e no Unix e derivados a leitura de fluxos como stdin --- teclado --- só retorna quando o usuário teclar ENTER.

 

A chave pra entender isso, que é uma m3rd@, é o que @Lucca Rodrigues citou do manual: se couber no limite n fgets() retorna inclusive o newline. Se não couber retorna só as letras até o limite. Se não ler nada não mexe na string, mas retorna NULL. Se você não testar o retorno não vai saber que não leu nada e vai ver a razão de centenas de questões em forums como esse: parece que o programa passa reto :D mas não passou.

 

Faz sentido, mas é chato pra caramba. 

 

Um exemplo mais concreto:

 

Na execução do programa abaixo a janela da direita "watch 1" mostra os valores das variáveis no momento do return.

 

O usuário digitou apenas  123467890 e teclou ENTER mas só cabem 3 na string um então o resto ficou pra depois...
 

image.png.8a21f07e01c64f5195405167c7e68823.png

 

 

Então o primeiro fgets() leu "123" e é o que temos: so cabem 3 porque é uma string.

 

No entanto o resto ficou lá e "456" acabou em dois e aí o terceiro fgets() que pode ler até 14 pegou o resto e colocou em tres. Como tinha espaço, leu "7890" e colocou o newline depois, com o valor 10. Claro, depois vem um 0 porque é a definição.

 

Instintivamente um iniciante espera que cada fgets() "comece do zero a ler de novo, mas não é assim e não faria sentido ser assim. Se um programa quer assim deve programar isso...

 

Esse programa do exemplo "passa reto" pelos fgets() consumindo o que tinha para ler...

 

 

 

 

 

 

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...