Ir ao conteúdo

Posts recomendados

Postado

Fala galera tudo bom?

Bom, eu estava dando uma pesquisada e reparei que o uso do "gets()" não é muito recomendado e eu encontrei isso "%[^\n]s" , pra meio que substituir, porém eu não sei se estou utilizando de maneira incorreta pois meu algoritmo não funciona utilizando isso, alguém sabe porque?

 


int main()
{
       char nomes[5] [10];
       int i,op;

       for(i=0; i<5; i++)
       {
            printf("Digite o %d nome: ",i+1);
            scanf("%[^\n]s", &nomes[i] );
       }

       printf("\n\nDigite um numero entre 1-5: ");
       scanf("%d",&op);


       printf("\n\nO valor %d se refere ao seguinte nome: %s",op,nomes[op-1]);

}

** Eu estou usando as seguintes bibliotecas:

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

 

  • Curtir 1
Postado

Não vai s no final do " %[^\n]", e coloque um espaço após a primeira aspas duplas " para descartar caracteres vazios que sobrarem da leitura anterior. Mas o correto mesmo seria limitar o número de caracteres a serem capturados para não estourar o comprimento do vetor de caracteres, nesse caso como o vetor de caracteres tem 10 posições (nove caracteres + 1 caractere nulo '\0') ficaria " %9[^\n]", sem isso usar %[^\n] no scanf() fica tão inseguro quanto o gets().

 

Outro problema do seu código é que você colocou & antes de nomes[ i ], & serve para pegar a referência/endereço de memória de uma variável, mas isso não deve ser feito em vetores (1 linha da matriz = 1 vetor) pois o nome de um vetor já é uma referência.

 

Logo, mude o comando para:

scanf(" %9[^\n]", nomes[i]);

 

  • Curtir 1
  • Obrigado 2
Postado

@MatheusINF Olá. Quanto a essa questão:

10 horas atrás, MatheusINF disse:

reparei que o uso do "gets()" não é muito recomendado

Exato! O comando gets é considerado um comando perigoso e inclusive nas IDEs mais atuais, como o Visual Studio, esse comando nem é mais aceito. Não recomendo de forma alguma o uso do gets em seus projetos para leitura de uma string.

Uma boa alternativa para a leitura de strings foi dada acima pelo @isrnick usando o scanf.

Outra alternativa q surgiu exatamente para substituir o gets é o fgets.

Usando seu código mesmo dá para demonstrar uma forma recomendada para usar o fgets. A princípio pode parecer complicado, mas a lógica usada é bastante simples e aí cedo ou tarde você vai entender bem o q está sendo feito

Segue seu código com o uso do fgets:

#include <stdio.h>
#include <string.h> // para as funções strtok e strlen

int main() {

    char nomes[5] [10];
    int i,op;
    char ch;

    for (i = 0; i < 5; i++) {

        printf("Digite o nome %d: ", i + 1);
        fgets(nomes[i], 10, stdin);
        strtok(nomes[i], "\n");
        if (strlen(nomes[i]) == 10 - 1) {
            while ((ch = getchar()) != '\n' && ch != EOF); // aqui o q é feito é basicamente usar a função getchar() em um loop
        }
    }
    printf("\n\nDigite um numero entre 1-5: ");
    scanf("%d",&op);

    printf("\nO valor %d se refere ao seguinte nome: %s\n\n", op, nomes[op - 1]);

    return 0;
}

Não se assuste com o fgets a primeira vista. É só questão d tempo para você entender bem o q está sendo feito.

Inclusive prefiro usar o fgets para ler uma string nos projetos q crio

 

Postado

Também seria interessante, se você gostou da função fgets, e precisar ler duas ou mais strings em um projeto seu, fazer uso de uma função tal como essa:

void read_string(char *the_string, int size) {
    char ch;
    fgets(the_string, size, stdin);
    strtok(the_string, "\n");
    if (strlen(the_string) == size - 1) {
        while ((ch = getchar()) != '\n' && ch != EOF);
    }
}

E aí, para usar essa função em seu código para a leitura de strings seria dessa forma:

for (i = 0; i < 5; i++) {
    printf("Digite o nome %d: ", i + 1);
    read_string(nomes[i], 10);
}

A grande vantagem d usar uma função como essa (q  té pode ser melhorada, caso alguém tiver alguma sugestão) é q você evita o erro de duplicidade de código em seus projetos

Obs: Claro q uma função como essa não pode ser comparada com um função como a função readLine, da biblioteca simpio que Eric Roberts escreveu, e pode ser vista com mais detalhes no arquivo simpio.c no link abaixo, mas, se Deus permitir, a gente chega lá

https://www.ime.usp.br/~pf/Roberts/C-library/standard/

Ou em sua forma adaptada aqui:

https://www.ime.usp.br/~pf/algoritmos/aulas/io2.html

Postado

Eu gosto da versatilidade da função scanf() permite fazer algumas coisas que não dá com fgets(), nesse caso permite descartar espaços, tabulação, etc no começo string digitada pelo usuário.

 

Então se o usuário digitar "    abcde\n", fgets() captura  "    abcde\n", mas scanf() com " %[^\n]" captura "abcde".

 

@giu_d fiz como ficaria a sua função read_string usando scanf:

void read_string(char *the_string, size_t size) {
    char ch, format_string[50];
    sprintf(format_string, " %%%zu[^\n]", size-1);
    scanf(format_string, the_string);
    while ((ch = getchar()) != '\n' && ch != EOF);
}

 

  • Curtir 2

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

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!