Lendo strings com espaço em branco usando scanf

Publicado por Paulo Roberto Santos de Sousa em 08/12/2005

[ Hits: 95.344 ]

 


Lendo strings com espaço em branco usando scanf



Olá!

Aí vai uma dica para os amantes de C que adoram usar scanf para ler dados do teclado. Muitos até já publicaram dicas para ler strings com scanf, mas as se depararem com o espaço em branco encontram uma certa dificuldade.

Pois a partir de um espaço em branco o scanf não lê mais os caracteres restantes, imprimindo apenas os caracteres que se encontram antes do espaço em branco. Bom chega de explicações, vamos para a prática.

Vejam abaixo dois códigos-fonte com alterações apenas no scanf:

Código 1:



#include <stdio.h>

int main()
{
  char str[20];
  scanf("%s",str);
  printf("A string digitada foi: %s\n", str);
  return 0;
}

Código 2:

#include <stdio.h>

int main()
{
     char str[20];
     scanf("%[A-Z a-z]",str);
     printf("A string digitada foi: %s\n", str);  
     return 0;
}


No código 1 utiliza-se normalmente o scanf. Já no código 2 o scanf irá ler caracteres de todo alfabeto em maiúsculo, o espaço em branco e minúsculo, respectivamente.

Falou pessoal, espero que aprovem a minha primeira diga. Até mais!!!

Outras dicas deste autor
Nenhuma dica encontrada.
Leitura recomendada

Funções de data usando time.h

Configuração de rede Debian - Erro: "Não Gerenciável" [Resolvido]

Atualização do Ubuntu passando por proxy

Mantendo logs do SMTP para auditoria em servidores de grande movimento

Instalando Firefox 5 no Ubuntu - PPA

  

Comentários
[1] Comentário enviado por EnzoFerber em 08/12/2005 - 21:11h

Cara... foi uma boa dica... írá ajudar os iniciantes... mais tem um jeito mais fácil... você pode usar a função do jeito que você colocou ou então colocar o seguinte no scanf();

#include <stdio.h>

int main(){
...
scanf("%[^\n]", str);
...
}

A instrução [^\n] diz ao comando scanf() para ler tudo até encontrar retorno de carro (ENTER)... no caso, representado pelo simbolo '\n'...
Mais foi uma boa dica para os que estão iniciando agora... valeu! ;-)
Abraço

[2] Comentário enviado por neophd em 14/12/2005 - 12:34h

Valeu cara. Super dez essa dica do scanf. Até mais!

[3] Comentário enviado por removido em 03/05/2006 - 11:08h

Eu uso as strings assim:
#include<stdio.h>
typedef char tstr[20];
int main(){
tstr text;
printf("\n\n\t Escreva o texto:");
scanf("%s",text);
printf("\n\n\t Texto inserido: %s",text);
return 0;}


Eu axo mais simples e organizado****

[4] Comentário enviado por ivrj em 31/10/2006 - 23:03h

para esse caso:
#include <stdio.h>

int main(){
...
scanf("%[^\n]", str);
...
}
deve-se dar um getchar(); logo apos o scanf no caso de haver outro scanf logo apos

[5] Comentário enviado por AboutDiego em 02/11/2006 - 23:09h

Também pode-se utilizar o fflush(stdin); logo após uma utilização do

scanf("%[^\n]",&str);

Terá o mesmo efeito, apesar que recomendo a utilização do fflush(stdin); pois ele serve para a limpeza de buffer do teclado ^^, falou galera.

[6] Comentário enviado por JoãoP. em 02/04/2007 - 14:56h

Nada do que foi comentado acima realmente funcionou em meu IDE (Bloodshed Dev-C++).

[7] Comentário enviado por JoaoP. em 02/04/2007 - 22:26h

Queria corrigir o que eu escrevi acima, funcionou sim, muito boas as dicas.
Só queria chamar atenção que é preciso(pelo menos no meu caso) usar fflush(stdin) antes de cada scanf, o meu não tava lendo corretamente justamente por isso.

Ps: Não editei a mensagem acima porque não tinha como, ou se tinha eu não vi =/
*primeiro dia no forum....fazer o que ^^*

[8] Comentário enviado por alcidesjr em 11/09/2007 - 10:22h

galera tentei de tudo mais nenhum desses funcinou para esse meu código...
é um trabalho da faculdade para criar contas, uma símulação de abertura de conta.

se alguem puder olhar e me ajudar....
agradeço!!!

#include<iostream>
#include<stdio.h>

using namespace::std;

typedef struct
{
char status;
char nu_conta[8];
char name_tit[80];
char endereco[100];
char date_cnt[10];
char type_cnt[9];
float sald_cnt;
float lim_chq;
char venc_cnt[10];
char tele_num[15];
char email_tit[50];





}cen_tab;

int num_reg=0;
cen_tab reg_bank[100];

void abr_cnt();
void fch_cnt();
void cst_cnt();
void lst_cnt();
void alt_cnt();
void exit_mn();




int main()
{
int menubnk;

do{
cout<<"******Menu_Bank**********\n";
cout<<"**** 1 - Abrir conta ****\n";
cout<<"**** 2 - Fechar conta ***\n";
cout<<"**** 3 - Consultar conta*\n";
cout<<"**** 4 - Listar contas **\n";
cout<<"**** 5 - Alterar conta **\n";
cout<<"**** 6 - Sair ***********\n";
cout<<"*************************\n";
cin>>menubnk;

switch(menubnk)
{
case 1:
abr_cnt();

break;

case 2:

fch_cnt();
break;

case 3:

cst_cnt();
break;

case 4:

lst_cnt();
break;

case 5:

alt_cnt();
break;

case 6:

exit_mn();
break;

}


}while(menubnk!=6);




}
//TODOS OS VOID'S///////////////////////////////////////////////////////////////
//void para o case 1, abrir conta///////////////////////////////////////////////
void abr_cnt()
{
char tipo_cnt;
int tipoi;
char pri_nome[50];
char sec_Nome[50];

reg_bank[num_reg].status=1;
cout<<"Digite o nmero da nova conta a ser inserida\n";
cin>>reg_bank[num_reg].nu_conta;
//*cout<<"Digite o nome do titular da conta:\n";
//*scanf("%s",reg_bank[num_reg].name_tit);
cout<<"primeiro nome\n";
cin>>pri_nome;
cout<<"Digite o segundo nome\n";
scanf("%[^\n]", sec_Nome);
cout<<"primeiro " <<pri_nome <<"segundo " <<sec_Nome;
cout<<"Digite o endereo do titular:\n";
cin>>reg_bank[num_reg].endereco;
cout<<"Digite data de abertura da conta:\n";
cin>>reg_bank[num_reg].date_cnt;

do{
cout<<"Digite (e) para conta especial e (c) para conta comum.:\n";
cin>>tipo_cnt;
if(tipo_cnt == 'e')
{
strcpy(reg_bank[num_reg].type_cnt, "Especial");
}
if(tipo_cnt == 'c')
{
strcpy(reg_bank[num_reg].type_cnt, "Comum");
}
}while(tipo_cnt != 'c' || tipo_cnt != 'e' );

cout<<"Digital o saldo atual da conta.";
cin>>reg_bank[num_reg].sald_cnt;
cout<<"Digite o limite do cheque especial.";
cin>>reg_bank[num_reg].lim_chq;
cout<<"Digite o vencimento do contrato.";
cin>>reg_bank[num_reg].venc_cnt;
cout<<"Digite o telefone do titular da conta.";
cin>>reg_bank[num_reg].tele_num;
cout<<"Digite o e-mail do titular da conta.";
cin>>reg_bank[num_reg].email_tit;
num_reg++;










}

[9] Comentário enviado por AboutDiego em 11/09/2007 - 17:51h

Utilize a função gets() para leitura de strings e sempre esvazie o buffer do teclado como o JoaoP. comentou. Deve funfar ^^ falouzz.

[10] Comentário enviado por removido em 23/10/2007 - 14:11h

Dica muito boa, porém não consegui fazer funcionar em uma estrutura
struct dados {
char nome[10];
ETC..
printf ("Nome: ");
scanf ("%s]",campo[i].nome);

Alguém tem alguma ideia, há uso linux antes que alguem diga para usar GETS. Obrigado

[11] Comentário enviado por AboutDiego em 23/10/2007 - 16:59h

Se vc utilizou realmente esse código sem alterar nada da fonte original, eu recomendo vc tirar o ']' que está logo após o %s na leitura hehee.
Falou.

[12] Comentário enviado por removido em 05/11/2007 - 11:06h

Esse ] foi de metido msm, foi nas tentativas que esqueci de apaga-lo, mas não funciona pra fazer a leitura.

[13] Comentário enviado por quartodazona em 01/06/2008 - 12:36h

Meu amigo PHD, muito boa dica mesmo. Funciona muito bem em estruturas sim, eu acabei de testar na linha de comando do gcc no Linux.
Boa, salvou meu dia.

[14] Comentário enviado por Ghalox em 26/01/2009 - 12:01h

Cara, a dica foi de muito bom uso pra mim, porque eu estava com esse mesmo problema há semanas e ainda não tinha encontrado uma resposta. O único porém é que tive que descobrir que a função para limpar o buffer do teclado no Linux é o __fpurge(stdin);.

[15] Comentário enviado por neophd em 26/01/2009 - 18:46h

Olá!
Você pode usar também fflush(stdin).

Até mais!

[16] Comentário enviado por removido em 04/01/2010 - 02:27h

Digite um número qualquer no scanf() e seu "algorítmo" irá pros ares.

@neophd

Não é preciso usar o fflush(stdin); no linux, o único compilador que tem problema com o scanf() é o DEV C++. Ele não limpa o buffer, portanto, o programador deverá entrar com o comando fflush(stdin); para limpar o buffer. No GCC isso é completamente desnecessário.

[17] Comentário enviado por junior_lavina em 24/10/2010 - 20:55h

Ai, pessoal
sou novo por aqui e gostaria de agradecer muito a vocês. Tinha um trabalho da Faculdade para entregar e essa dica salvou minha vida.

Muitíssimo grato!

Junior_lavina
Estudante de Sistemas de Informação - Bacharelado

[18] Comentário enviado por wesleygalvao em 06/03/2013 - 19:51h

Bom, galera. Alguém poderia me ajudar com uma dúvida?
Gostaria verificar se uma frase qualquer contém espaçamentos desnecessários, ou seja, se existem uma sequencia de mais de um espaço entre palavras, e fazer uma compactação, deixando apenas um espaço entre uma palavra e outra.

[19] Comentário enviado por neophd em 07/03/2013 - 11:35h

Olá! Uma forma seria vc substituir 2 espaços em branco por 1.
Segue abaixo um código em C++ que utiliza essa idéia:

#include <iostream>
#include <string>
using namespace std;
int main ()
{
string str ("There are two needles in this haystack with needles.");
string str2 (" ");

unsigned found = str.find(str2); // retorna a posição de onde começa a 1a ocorrência da string procurada
while (found!=string::npos) { // enquanto achar 2 espaços em branco consecutivos executa o código do bloco abaixo
str = str.substr(0,found) + str.substr(found+1); //substitui a string atual pela string sem 1 espaço em branco
found = str.find(str2); // procura novamente 2 espaços em branco consecutivos
}
cout << str;
return 0;
}

Uma forma mais eficiente seria utilizar expressão regular.

Espero ter ajudado.
Até mais!



Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts