Scanf aprimorado

#include <stdio.h>

int main(){

char s[50];

printf("Digite algo(scanf convencional):\n");
scanf("%s",s);
fflush(stdin);

printf("Resultado:%s\n\n",s);

printf("Digite algo(scanf aprimorado):\n");
scanf("#50[^\n]s",s);
fflush(stdin);

printf("Resultado:%s\n\n",s);

}

Porque esse programa não executa perfeitamente no codeblocks do Linux?

Observação:Não sei se fiz algum tópico semelhante a esse.

Não funciona porque no segundo scanf, o especificador de formato deve começar com %, e não #.

Mas ainda sim tem outro problema. fflush deve ser usado com streams de saída. Ao passar stdin, que é uma stream de entrada, o comportamento é indefinido. Ele pode até “funcionar” em algum ambiente, mas não é garantido que funcione em todos (não é portável). Leia aqui para mais detalhes. Tem outras formas de limpar o buffer de entrada, abaixo coloquei uma sugestão:

void clearBuffer(FILE *fp) {
    int c;
    while ((c = fgetc(fp)) != EOF && c != '\n');
}

int main() {
    char s[50];

    printf("Digite algo(scanf convencional):\n");
    scanf("%s", s);
    printf("Resultado:%s\n\n", s);
    clearBuffer(stdin);

    printf("Digite algo(scanf aprimorado):\n");
    scanf("%50[^\n]s", s);
    printf("Resultado:%s\n\n", s);
    return 0;
}
1 curtida

Só complementando, se o objetivo é ler strings, uma forma apropriada é usando a função fgets.

/* char *fgets ( char *str, int num, FILE *stream )
 *        char *str: ponteiro para a string que armazenará
 *                   a leitura.
 *          int num: limite de caracteres suportados
 *                   (incluindo o '\0').
 *     FILE *stream: um ponteiro para arquivo,
 *                   usaremos stdin.
 * Retorna o próprio ponteiro passado caso tenha sucesso
 * ou o ponteiro NULL caso haja algum erro na leitura.
 */
char string[30];
printf( "Entre com a string: " );
fgets( string, 30, stdin );
string[strlen(string)-1] = '\0'; // remove o pulo de linha

Se quiser um material de linguagem C com exercícios dá uma olhada no meu livro: https://github.com/davidbuzatto/Releases-Livro-Coletanea-Exercicios-C/releases/download/v1.0.3/2023.-.Coletanea.de.Exercicios.e.Notas.de.Aula.em.Linguagem.de.Programacao.C.-.correcoes.03.pdf

É um livro para ser usado na disciplina que leciono. Não é um livro texto, mas da para vc usar os exercícios.

[]'s

2 curtidas

Perfeito, de fato scanf tem uma série de problemas e é preferível usar fgets. Eu nem quis entrar nesses detalhes pra não ficar longo demais, mas já que é pra complementar:

Inclusive, o último link cita o uso de strcspn, que trata os casos em que vc digita mais do que o tamanho indicado no fgets (pois aí não terá o \n no final).

Enfim, lidar com I/O em C é um mundo à parte. Nem tem como cobrir tudo aqui. Mas só de advertir quanto ao uso de fflush(stdin) acho que já valeu o tópico :slight_smile:

2 curtidas