Ir ao conteúdo
  • Cadastre-se

Duvida ao imprimir nome completo


AloneSmile
Ir à solução Resolvido por dontpanic,

Posts recomendados

A duvida é o seguinte estou utilizando uma struct para guardar o registro dos alunos, abaixo segue um exemplo:

#include <stdio.h>typedef struct tAluno {    char nome[30];} Aluno;static Aluno alunos[30];main(){    int index=0;    printf("Informe o nome do aluno: ");    scanf("%s", alunos[index].nome); fflush(stdin);    printf("Aluno: %s\n", alunos[index].nome);}

E na hora de imprimir na tela aparece apenas o primeiro nome digitado, a função não captura qualquer carácter apos o espaço, okay.

 

Abaixo segue um exemplo do resultado que quero chegar:

#include <stdio.h>#define TAM 30int main(){	char nome[TAM];	fgets(nome, TAM, stdin);	printf( "%s\n", nome);	return 0;}

Aqui imprime tudo digitado pelo usuário.

Em, fim, queria saber se tem como juntar estas duas funções por exemplo:

fgets(alunos[index].nome, TAM, stdin); fflush(stdin);

Agradeço desde já, e espero que tenham entendido, obrigado.

Link para o comentário
Compartilhar em outros sites

Uai... você mesmo já respondeu sua pergunta. o__O

O scanf captura uma palavra apenas (captura um stream até achar um espaço em branco), o fgets captura uma frase inteira (captura a stream até achar uma quebra de linha).

Então é só usar o fgets em vez do scanf, como você mesmo já observou no seu exemplo.

Link para o comentário
Compartilhar em outros sites

Pois é kkk, neste código ai funcionou, eu já ia até apaga-lo, mas deixei, vai que alguém precise disso algum dia.

Como eu disse esse ai é um exemplo, em, fim, o outro que realmente quero resolver de 500 linhas, por enquanto, esta nesta situação, e esta ocorrendo o seguinte, ele não espera o usuário informar o nome e já pula para a próxima instrução, entende.

Link para o comentário
Compartilhar em outros sites

Geralmente é porque ainda fica alguma coisa no buffer do stdin, daí quando você vai abrir o stdin de novo com alguma função tipo scanf ou fgets, essas funções acabam lendo o "lixo" que tava no stdin em vez de pegar do teclado. Se quiser pode postar o código aí pra gente ver se dá pra corrigir.

 

Se quiser uma sugestão, tente isolar no seu programa a parte de pegar input do usuário... faça uma função à parte só pra isso, daí teste ela em diferentes situações pra saber se tá funcionando.

 

Eu fiz isso uma vez usando a função getchar(), daí eu tinha mais controle sobre o stdin pois lia character por character.

 

Exemplo:

#include <stdio.h>void meuLindoInput(char* in) {    char c;    int i = 0;    do {        c = getchar();        in[i++] = c;    } while (c != '\n');    in[i] = '\0';}int main (){  char strg[30];  meuLindoInput(strg); // em vez de usar scanf ou fgets, você usa sua própria função pra pegar input  printf("%s", strg);  return 0;}
Link para o comentário
Compartilhar em outros sites

Boa ideia.

Entendi, essa função funciona semelhante ao scanner em java:

package scanneer;import java.util.Scanner;// importar metodo Scannerpublic class Scanneer {public static void main(String[] args) {    String nome;    Scanner en = new Scanner(System.in);    //Chamando o metodo Scanner a receber os valores em en    System.out.println("Informe o seu nome: ");    nome = en.nextLine();    //Nome vai receber o valor informado em en        System.out.println(""+nome);        }}

Em fim, olha resumi o máximo aqui para que você possa entender 

#include <stdio.h>#include <stdlib.h>#include <conio.h>#include <string.h>#include <locale>#include <time.h>#define tam 30//struct utilizando-a para guardar o registro dos alunos//Cada aluno tem um nome e 4 notas pra cada matériatypedef struct tAluno {    char nome[30];    float notas[13][4]; // 4 notas pra cada uma das 13 matérias} Aluno;//Declarando as variavéisint op = 0, op2 = 0, i = 0, j = 0, index;char opcao[25];char c;float me = 0, soma = 0;static Aluno alunos[30];//Declarações das funções e subrotinasvoid capInput(char* in);void cadastro();void imprimir();void imprimeMenu();void cabecalho();//Programa principalmain(){	int pergunta, sairdosubmenu = 0;	setlocale(LC_ALL ,"Portuguese");	system("cls");   while(true){   		imprimeMenu();   	if(op == 4)	return 0;   	if (op==1){//ini op 1   		do{//ini do   			cabecalho();   			switch(op2){//ini switch   				case 1:   					system("cls");   					printf("\t\tOPÇÃO 1..............CADASTRO: \n\n");   					//Desenvolvimento   					cadastro();   					printf("\n\n\t\tDigite alguma tecla para voltar\n");   					scanf("%s", &pergunta); fflush(stdin);//dobradinha   					system("cls");   				break;    			case 2:   					system("cls");   					printf("\t\tOPÇÃO 3..............IMPRIMIR: \n\n");					//Desenvolvimento					imprimir();   					printf("\n\n\t\tDigite alguma tecla para voltar\n");   					scanf("%s", &pergunta); fflush(stdin);   					system("cls");   					break;   				case 3:   					system("cls");   					printf("\t\tOPÇÃO 4..............AJUDA: \n\n");					//Desenvolvimento					//ajuda();   					printf("\n\n\t\tDigite alguma tecla para voltar\n");   					scanf("%s", &pergunta); fflush(stdin);   					system("cls");   				break;    			case 4:    				sairdosubmenu = 1;				break;				default:					printf("Opção Inválida");   			   }//fim switch				if(sairdosubmenu){//ini if sairdosubmenu    				system("cls");    				sairdosubmenu = 0;    				break;				}//fim if sairdosubmenu   		   }//fim do		while (pergunta!=1);	   }//fim op 1   }//fim while(true)getch();return 0;}//Funçõesvoid capInput(char* in){//Capturar o input do usuário    do {        c = getchar();        in[i++] = c;    } while (c != '\n');    in[i] = '\0';}void cadastro(){        printf("\nInforme o nome do aluno: ");        //Funciona        //scanf("%s", alunos[index].nome); fflush(stdin);        //Não Funciona   	//fgets(nm, tam, stdin);   	//Não Funciona   	capInput(alunos[index].nome);}void imprimir(){		printf("Aluno: %s\n", alunos[index].nome);}void imprimeMenu(){   	 	printf("\t\t\t OLÁ SEJA BEM-VINDO AO PROGRAMA DE \n");   		printf("\t\t\t LANÇAMENTO DE MÉDIAS ANUAL DE UMA \n");  		printf("\t\t\t TURMA DO ENSINO MÉDIO \n\n"); 		printf(" * Escolha uma opção:  \n\n"); 		printf("1 - Prosseguir  4 - Encerrar\n");   		scanf("%d", &op);   		system("cls"); //limpa tela}void cabecalho(){		system("cls");  		printf("\t 1 ...... CADASTRO\n"); 		printf("\t 2 ...... IMPRIMIR\n"); 		//printf("\t 3 ...... AJUDA\n"); 		printf("\t 4 ...... VOLTAR AO INICIO\n"); 		printf("................................................................................\n"); 		scanf("%d", &op2);}

Para fazer o teste é só:

Clicar 1 para prosseguir 

1 para entrar no cadastro e informar o nome completo

Depois digitar qualquer numero

2 para Imprimir

 

Ai que esta a duvida, quando uso 

scanf("%s", alunos[index].nome); fflush(stdin);

Funciona, porém não imprime o nome completo, como você já explicou...

 

Quando uso 

fgets(nm, tam, stdin);oucapInput(alunos[index].nome);

Não funciona, entende, já pula para a próxima instrução sem deixar que possa digitar algo.

Link para o comentário
Compartilhar em outros sites

  • Solução

Um bug que eu achei: scanf("%s", &pergunta); --> pergunta é um int, mas você tá passando ele pro scanf como string

 

Quanto ao motivo do erro, é o seguinte:

Quando a função main chama a função imprimeMenu(), você escolhe uma opção e o scanf guarda o valor em 'op', certo?

 

scanf("%d", &op);

 

Imagine o buffer do stdin como uma mangueira. De um lado fica entrando água (a torneira, ou seja, o teclado alimentando as teclas) e do outro fica vazando água (a saída, ou seja, o scanf/fgets/etc).

 

Digamos que você digite '1' e depois aperte ENTER pra confirmar ('\n').

Então a mangueira do buffer fica aqui:

 

saída --> [1] ['\n'] [ ] [ ] [ ] [ ] ... <-- entrada

 

O buffer captura tanto o número que você digitou quanto o ENTER.

E o scanf tava esperando um número (%d) então ele vai no buffer e retira o número de lá e guarda em 'op'.

Mas aquele enter que você digitou ainda fica no buffer:

 

['\n'] [ ] [ ] [ ] [ ] ...

 

Daí agora você saiu da função imprimeMenu, o main chama a função cabecalho() e essa função usa o scanf novamente:

 

scanf("%d", &op2);

 

Dessa vez em vez de esperar você digitar algo, a função vai checar o buffer do stdin e vai ver que ainda tem um valor lá (o enter que sobrou) e já vai pegar esse valor ('\n') e colocar em 'op2', achando que foi um número que você digitou. Normalmente quando você tem um monte de printf() depois de um scanf(), o buffer acaba sendo limpo automaticamente, pois tanto o printf quanto o scanf usam o mesmo buffer. Mas quando você usa dois ou mais scanf()'s próximos um do outro (que é o caso entre a função cabecalho() e cadastro()) daí o lixo de um acaba passando pro outro.

 

Pra resolver isso você tem algumas opções:

- Usar o fflush(stdin):

Essa função supostamente esvazia o buffer. Então bastaria você usar ela nas funções imprimeMenu() e cabecalho() depois dos scanf() pra garantir que as próximas funções vão receber o buffer vazio). O único problema do fflush() é que ela não é muito segura... por exemplo, no linux nem sempre ela faz o que se propõe, e alguns compiladores implementam ela de jeito diferente. Então teste antes pra ver se tá limpando o buffer mesmo.

 

- Manipular o scanf() pra ele já ignorar o ENTER depois de pegar um número ou character:

Essa é meio gambiarra, mas você pode usar por exemplo:

scanf("%d", &op); --> captura um numero do buffer e guarda em op

scanf("%*c"); --> captura e descarta um char do buffer (o enter que sobrou)

 

- Criar uma função só pra pegar números, usando o getchar(), assim como eu fiz lá com a função de capturar nomes. Daí você tem mais controle sobre o buffer.

Link para o comentário
Compartilhar em outros sites

Quando eu quero gravar nomes, faço assim:

// Program C'11 - for_code.c#include  <stdio.h>int main( void ){    char Name[ 21 ] = { 0 }; //Inicializa todos com \0(zero);        printf( "-----------------------\n" );        printf( "Qual o seu nome?\n$Name> " );        scanf( "%20[^\n]", Name );        printf( "-----------------------\n" );        printf( "Seu nome %s\nQue bonito nome!\n\n", Name );        return ( 0 );}
  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Ou então, essa versão que fiz para um exercício:

// mauro - Program C'11 - for_code.c#include  <stdio.h>char *PegaStrings( int tam, char Vetor[tam] );int main( void ){    char name[21];        printf( "-------------------------\n" );        printf( "Qual o seu Nome?\n$Name> " );        if( PegaStrings( 21, name )!= NULL ){            printf( "-------------------------\n" );            printf( "%s! nome interessante,\ne bonito tambem!!!\n", name );        }else            printf( "Acabou!\n" );return ( 0 );}char *PegaStrings( int tam, char Vetor[tam] ){    char *strings = NULL;        strings = fgets( Vetor, tam, stdin );        if( strings == NULL )return NULL;        int index;        for( index = 0; index < tam; index++ ){            if( strings[ index ]== '\n' ){                strings[ index ]= '\0';                break;            }        }        if( index == tam )            while( getchar() != '\n' )                continue;return Vetor;}

:)

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está impedido de receber novas respostas.

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