Ler UM char em C++

Spiderman

I folded Myself
Tenho aqui um quebra cabeças engraçado para resolver.

Preciso, numa dada altura do programa de lêr um char dado pelo utilizador.
Só que se o utilizador, por alguma razão mete mais de um, o programa vai bloquear todo.
Eu utilizei a função normal:

cin>>var_char;

Já tentei com o "scanf", mas depois aquilo lê-me o enter (paragrafo), em vez de ler o caracter que là está.

Como é que eu faço para ler apenas o 1º caracter, ou ate mesmo, caso tenha mais de um caracter, dizer ao utilizador para pôr apenas um, e voltar a lêr.

Eu pensei em ler para uma string normal, e depois fazer algo assim:

var_char=string[0];

Mas tambem não me deu...

Alguma solução?

:confused:
 
Funcionar funciona, mas a versão C++ do getchar() é o cin.get()

Código:
int o_meu_caracter = cin.get();
char o_meu_caracter_em_forma_de_char = (char)o_meu_caracter;
 
Bom, achei o problema interessante e perdi aqui umas horitas a tentar encontrar uma solução. Aquilo que encontrei foi um conjunto de funções de tratamento do input, entre as quais a tty_getchar() que só permite que seja introduzido 1 caracter e logo a seguir passa para a instrução seguinte. Como tal, só podes introduzir 1 letra ou um dígito! Ex:

Código:
#include <stdio.h>
#include <conio.h>

int tty_getchar()
{
    return getche();
}

int main() {
    char i;
    i=tty_getchar();
    printf("Introduziu: %c",i);
    return 0;
}
O único senão é o <conio.h> por causa do getche().

Podes ler mais aqui:

http://c-faq.com/osdep/cbreak.html
http://www.mtm.ufsc.br/~azeredo/cursoC/aulas/c920.html

EDIT: Talvez consigas algo igual utilizando a biblioteca ncurses.
 
Última edição:
não esta a dar...
Vou pôr aqui o codigo, que é para mostrar melhor:

Código:
char charTmp;
string nomeTmp;
	
cout << "Nome do Jogador 1: ";
cin >> nomeTmp;
cout << "Simbolo do Jogador 1: ";
cin >> charTmp; //Problemas neste!!!

Baderous, obrigado pela disponibilidade e empenho. Infelizmente, não esta a dar. Por alguma razão o codigo bloqueia depois de eu meter o nome do jogador. Simplesmente não avanca o jogo, e ficamos ali a escrever caracteres e carregar em enter's...

A outra maneira que o Mr_Miguel disse, simplesmente tem o mesmo problema que o que eu ja tentei: O pc lê o "enter", ao inves de ler o caracter que la esta....

Só se houver alguma maneira de limpar o buffer....
 
Se o problema é limpar o buffer...

Código:
scanf[COLOR=#66cc66]([/COLOR][COLOR=#ff0000]"%*[^[COLOR=#000099][B]\n[/B][/COLOR]]"[/COLOR][COLOR=#66cc66])[/COLOR]; scanf[COLOR=#66cc66]([/COLOR][COLOR=#ff0000]"%*c"[/COLOR][COLOR=#66cc66])[/COLOR];
http://www.portugal-a-programar.org/forum/index.php/topic,12638.0.html

PS: Agora que vi este teu post, voltei a ler o 1º post e vi qual era a dúvida...e eu para aqui a inventar...eu pensei que querias que o programa bloqueasse em caso de ser inserido mais do que 1 char!!
 
Última edição:
Ve se isto resolve o teu problema:


Código:
#include <iostream>
#include <string>


#define MAX 10

using namespace std;

void main()
{

 char charTmp[MAX];
 string nomeTmp;
    
 cout << "Nome do Jogador 1: ";
 cin >> nomeTmp;
 cout << "Simbolo do Jogador 1: ";

 do{

    cin >> charTmp;
    if(strlen(charTmp)>1)
        cout<<endl<<"Erro! Introduza apenas um caracter!"<<endl<<endl;

 }while(strlen(charTmp)>1);

}
 
não esta a dar...
Vou pôr aqui o codigo, que é para mostrar melhor:

Código:
char charTmp;
string nomeTmp;
    
cout << "Nome do Jogador 1: ";
cin >> nomeTmp;
cout << "Simbolo do Jogador 1: ";
cin >> charTmp; //Problemas neste!!!
Baderous, obrigado pela disponibilidade e empenho. Infelizmente, não esta a dar. Por alguma razão o codigo bloqueia depois de eu meter o nome do jogador. Simplesmente não avanca o jogo, e ficamos ali a escrever caracteres e carregar em enter's...

A outra maneira que o Mr_Miguel disse, simplesmente tem o mesmo problema que o que eu ja tentei: O pc lê o "enter", ao inves de ler o caracter que la esta....

Só se houver alguma maneira de limpar o buffer....

Assumindo que o operador >> do "cin" deixa o '\n' no input (e até hoje, nunca vi nenhuma situação em contrário), o problema resolver-se-ia assim:

Código:
//Elimina todos os caracteres que existirem no input (incluindo o '\n')
void limparInput() {
    while (cin.get() != '\n');
}

(...)

cout << "Nome do Jogador 1: ";
cin >> nomeTmp;
cout << "Simbolo do Jogador 1: ";
limparInput();
cin >> charTmp;
 
Bom, achei o problema interessante e perdi aqui umas horitas a tentar encontrar uma solução. Aquilo que encontrei foi um conjunto de funções de tratamento do input, entre as quais a tty_getchar() que só permite que seja introduzido 1 caracter e logo a seguir passa para a instrução seguinte. Como tal, só podes introduzir 1 letra ou um dígito! Ex:

Código:
#include <stdio.h>
#include <conio.h>

int tty_getchar()
{
    return getche();
}

int main() {
    char i;
    i=tty_getchar();
    printf("Introduziu: %c",i);
    return 0;
}
O único senão é o <conio.h> por causa do getche().

Podes ler mais aqui:

http://c-faq.com/osdep/cbreak.html
http://www.mtm.ufsc.br/~azeredo/cursoC/aulas/c920.html

EDIT: Talvez consigas algo igual utilizando a biblioteca ncurses.

Quando falei em <ncurses.h>, também podia ter falado em <termios.h> e, segundo aquilo que eu pensava que querias, teria ficado assim:

Código:
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>

void changemode ( int );
int  kbhit ( void );

int main ( void )
{
   int ch;
   changemode ( 1 );

   ch = getchar();

   printf ( "\nGot %c\n", ch );

   changemode ( 0 );
   return 0;
}

void changemode ( int dir )
{
   static struct termios oldt, newt;

   if ( dir == 1 )
   {
      tcgetattr ( STDIN_FILENO, &oldt );
      newt = oldt;
      newt.c_lflag &= ~ ( ICANON | ECHO );
      tcsetattr ( STDIN_FILENO, TCSANOW, &newt );
   }
   else
      tcsetattr ( STDIN_FILENO, TCSANOW, &oldt );
}

int kbhit ( void )
{
   struct timeval tv;
   fd_set rdfs;

   tv.tv_sec = 0;
   tv.tv_usec = 0;

   FD_ZERO ( &rdfs );
   FD_SET ( STDIN_FILENO, &rdfs );

   select ( STDIN_FILENO + 1, &rdfs, NULL, NULL, &tv );
   return FD_ISSET ( STDIN_FILENO, &rdfs );

}

Neste exemplo, a função khbit não interessa, apenas interessa a changemode.
 
Já esta a dar!!!

Muito obrigado a todos. Ficou basicamente assim:

Código:
void limparInput() //Funcao para limpar o buffer do Input.
{
    while (cin.get() != '\n');
}

main(){
string nomeTmp;
char charTmp;

cout << "Nome do Jogador 1: ";
cin >> nomeTmp;
cout << "Simbolo do Jogador 1: ";
limparInput(); 
cin.get(charTmp);
}

:001:
 
Eu nao li a questão só msm para dizer, q em vez de criares essa função pah limpar o buffer do cin podes usar cin.ignore(),

cumprimentos
 
Back
Topo