Função boa para ler string em C

Publicado por Elgio Schlemer (última atualização em 16/01/2010)

[ Hits: 45.006 ]

Homepage: https://profelgio.duckdns.org/~elgio

Download lestring.c




Muitos tem certa dificuldade em ler strings em C, principalmente se usar o scanf, que não lê espaços em branco em sua forma original. Um artigo meu em http://www.vivaolinux.com.br/artigo/Parametros-interessantes-do-scanf-e-do-printf-em-C descreveu um pouco deste problema e aqui publico uma função em C que resolve estes problemas.

  



Esconder código-fonte

/* 
   TÍTULO: Função boa para ler strings 
      
   Uma função boa para ler strings que resolve o problema que o fflush resolveria
   A técnica é não aceitar string vazia. 

   Deve ser passada a string e o tamanho máximo

   A função NÃO DEIXA digitar mais do que o tamanho máximo e o que exceder este tamanho 
   NÃO SERÁ LIDO, ficando para a próxima função que realizar alguma leitura
*/

#include <stdio.h>
int lestring(char s[], int max)
{
    int i = 0;
    char letra;

    /* No caso o max é o tamanho que s pode receber. Deve ser passado o tamanho
       mesmo, ou seja, se for passado 100 a função já se encarrega de não deixar
       passar de 99 cars (+1 do finalizador)
     */
    for (i = 0; i < (max - 1); i++) {
   letra = fgetc(stdin);

   /* Veja que se encontrou um ENTER (\n) mas não leu nenhum caractere válido,
         * não aceita. Precisa ler algo. Decrementa o i para anular o efeito do i++ 
         * do laço e volta no laço com continue
    */
   if ((letra == '\n') && (i == 0)) {
       i = i - 1;
       continue;
   }

   /* Agora se leu um enter já tendo lido caracteres válidos, então 
    * o usuário terminou de digitar sua string e ela possui ao menos 
    * um caractere válido
    */
   if (letra == '\n')
       break;
   s[i] = letra;
    }

    /* Finaliza a string */
    s[i] = 0;

    /* retorna a quantidade de cars lidos (pode ser útil). Então, esta função
       lê uma string e retorna o seu tamanho
     */
    return (i);
}


// Exemplo de uso da lestring:
/* Dentro do main... */
#define MAXSTR 20
int main()
{
    char s[MAXSTR];
    int t;
    t = lestring(s, MAXSTR);
    printf("Você digitou %s\n", s);
    printf("E esta string tem %i cars\n", t);
    return (0);
}


/* Com esta função não precisa usar o fflush. Ela lê espaços em branco e não mais do 
 * que a capacidade da string. Muito melhor que o scanf, pois em sua versão original
 * não lê espacos. Melhor que o gets, pois o gets, assim como scanf, permite INVADIR
 * a string (overflow). Melhor que o fgets, pois não precisa limpar o buffer do 
 * teclado com fflush.
*/

Scripts recomendados

Boletim Escolar Com Manipulação de Arquivo

Manipulando árvores.

Relógio com data e hora

Classe para MySQL

Comando strieql


  

Comentários
[1] Comentário enviado por m1z0b3 em 16/01/2010 - 19:04h

o scanf te permite passar alguns parametros..
por exemplo se voce quiser ler uma string ate que ocorra uma quebra de linha

scanf(%[^n], &string)

modificando esse primeiro parametro e possivel ja validar uma entrada de dados com apenas letras maiusculas e outras necessidades...

[2] Comentário enviado por elgio em 17/01/2010 - 00:11h

Sim, mas o scanf ainda mantém os demais problemas:

a) o Enter que sobra (para o qual o pessoal usa fflush)
b) problemas com overflow
Muito embora seja possível limitar a quantidade de caracteres que o scanf irá ler - scanf("%50[^\n]s", nome) - isto não é nada prático por não permitir que o tamanho seja variável ou mesmo constante. Ainda assim a função aqui é extremamente útil.

Esta tua variação do scanf, bem como outras tanto do scanf quanto do printf foram abordadas por mim no artigo http://www.vivaolinux.com.br/artigo/Parametros-interessantes-do-scanf-e-do-printf-em-C

[]'s


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts