Ir ao conteúdo

Posts recomendados

Postado

Bom Dia Galera! Tudo bem?

 

Alguém pode me dar uma luz e dizer onde estou errando nesse código? 

 

Tenho que fazer um programa utilizando estruturas que permite a entrada de nome, endereço e telefone de 5 pessoas e depois imprime em ordem alfabética, ainda não fiz a parte da ordem somente a primeira parte que recebe os dados, quando roda ele pede certo o nome e endereço, mas na hora de pedir o telefone ele pula e já pede novamente o nome e endereço. Sou iniciante em C, não estou encontrando o erro, se alguém puder ajudar! 

 

Segue a primeira parte que estou tendo dificuldade: 

 
#include <stdio.h>#include <conio.h>struct agenda {        char pessoa[50],end[50];    int fone[15];};int main(){              int i;              struct agenda c[5];                 for (i=0; i<5; i++)       {        printf("\n Digite seu Nome: ");        scanf("%s",&c[i].pessoa);        printf("\n Digite seu Endereco: ");        scanf("%s",&c[i].end);        printf("\n Digite seu Telefone: ");        scanf("%d",&c[i].fone);      }  getch();}

 

Postado

cara não sei em C mas end normalmente é para finalizar algo

scanf("%s",&c[i].end);

já tive problemas no vba com nomes de funções e variarei que eram iguais a instruções já existentes que eu desconhecia, algumas somente davam erro com certos valores

 bem posso estar enganado, mas poderia tentar trocar o nome para ende

*metendo o nariz em algo que nem sei que cheiro tem :P

Postado

cara não sei em C mas end normalmente é para finalizar algo

scanf("%s",&c[i].end);

já tive problemas no vba com nomes de funções e variarei que eram iguais a instruções já existentes que eu desconhecia, algumas somente davam erro com certos valores

 bem posso estar enganado, mas poderia tentar trocar o nome para ende

*metendo o nariz em algo que nem sei que cheiro tem :P

 

Toda ajuda é bem vinda, obrigada eu troquei end por endereço. 

 

 

Em que no caso de strings você não precisa por o operador & adiante da variavel. troque scanf("%s",&c.pessoa); por scanf("%s",c.pessoa);

 

 Isso de não precisar colocar o operador de endereço é somente para strings né? Para inteiros eu coloco normal né? 

 

Eu troquei a palavra end por endereço e tirei os operadores das strings, ainda não funcionou :( 

 

Eu utilizo o Dev C++, o que poderia ser mais? 

Postado
#include <stdio.h>#include <stdlib.h>#define N_CONTATOS 2struct Dados {    char nome[50];    char dir[50]; //direçao    int fone;};int main() {    int i;        struct Dados agenda[N_CONTATOS];        for ( i = 0; i < N_CONTATOS; i++ ) {        printf ( "\nContato%d Digite seu Nome: ",i+1 );        scanf ( "%49[^\n]%*c", agenda[i].nome );                printf ( "\nContato%d Digite seu Endereco: ",i+1 );        scanf ( "%49[^\n]%*c", agenda[i].dir );                printf ( "\nContato%d Digite seu Telefone: ",i+1 );        scanf ( "%d%*c", &agenda[i].fone );                system("cls");    }    for ( i = 0; i < N_CONTATOS; i++ ) {        printf("Contato%d \nMome: %s \nResidencia: %s \nTel: %d\n\n", i+1, agenda[i].nome, agenda[i].dir, agenda[i].fone);    }            getchar();}

Si tiver duvidas pergunte ;)

 

Obrigada pela força, mas não posso usar #define nesse exercício ainda rsrsrs apenas a estrutura básica mesmo, nem ponteiros nada, fiquei sem entender os scanf que você fez aí, tem a ver com o #define?  

Postado

Não o #define apenas define um valor fixo pra um parâmetro, no caso ali ele definiu N_CONTATOS como igual a 2, então na prática você pode excluir a linha do #define e substituir todos os locais no resto do código onde está escrito N_CONTATOS pelo número 2... (Na prática o compilador faria essa substituição antes de compilar o código.)

 

Ele só fez desta maneira pra facilitar a alteração do número total de contatos, pra não ter que alterar todos os lugares todas as vezes.

 

Você também poderia usar uma variável inteira no main no lugar disto, que conteria o número de contatos...

 

 

 

Então sobre os scanfs...

 

Ele declarou no main uma struct Dados com nome agenda com 2 posições (ou seja pode armazenar 2 contatos).

struct Dados agenda[N_CONTATOS];

Então seria possível chamar as posições agenda[0] e agenda[1] da agenda.

 

 

Conforme a definição da struct Dados, cada elemento deste tipo possui 2 vetores de 50 caracteres, chamados "nome" e "dir", e 1 inteiro com nome "fone".

 

Aqui vem a distinção entre uma variável simples e um vetor... Quando você usa o nome da variável o que você obtém é o valor 'armazenado nela', e para obter o endereço/a referência da memória onde este valor está armazenado você usa o operador & antes do nome.

 

No caso de vetores entretanto para obter o valor armazenado em uma de suas posições é necessário indicar a respectiva posição entre colchetes [] após seu nome. Ex:

char vetor[6] = "abcde";if (vetor[0] == 'a')    printf("A posicacao 0 do vetor contem o caractere a.");

Se você usar apenas seu nome, sem colchetes o que você obtém já é o endereço de memória do vetor, portanto não é necessário usar o operador &.

Obs: Note que você deve usar o operador & nesse caso: &vetor[2] -> retorna o endereço na memória da segunda posição do vetor (no exemplo acima seria o endereço contendo o caractere 'c' da string).

 

Então observe que nos scanfs do código do @vangodp ele usa o operador & apenas no caso do "fone" (que é uma variável inteira da i-ésima posição da agenda), mas não usa o operador no "nome" nem no "dir", pois são vetores de caracteres.

Postado

Não o #define apenas define um valor fixo pra um parâmetro, no caso ali ele definiu N_CONTATOS como igual a 2, então na prática você pode excluir a linha do #define e substituir todos os locais no resto do código onde está escrito N_CONTATOS pelo número 2... (Na prática o compilador faria essa substituição antes de compilar o código.)

 

Ele só fez desta maneira pra facilitar a alteração do número total de contatos, pra não ter que alterar todos os lugares todas as vezes.

 

Você também poderia usar uma variável inteira no main no lugar disto, que conteria o número de contatos...

 

 

 

Então sobre os scanfs...

 

Ele declarou no main uma struct Dados com nome agenda com 2 posições (ou seja pode armazenar 2 contatos).

struct Dados agenda[N_CONTATOS];

Então seria possível chamar as posições agenda[0] e agenda[1] da agenda.

 

 

Conforme a definição da struct Dados, cada elemento deste tipo possui 2 vetores de 50 caracteres, chamados "nome" e "dir", e 1 inteiro com nome "fone".

 

Aqui vem a distinção entre uma variável simples e um vetor... Quando você usa o nome da variável o que você obtém é o valor 'armazenado nela', e para obter o endereço/a referência da memória onde este valor está armazenado você usa o operador & antes do nome.

 

No caso de vetores entretanto para obter o valor armazenado em uma de suas posições é necessário indicar a respectiva posição entre colchetes [] após seu nome. Ex:

char vetor[6] = "abcde";if (vetor[0] == 'a')    printf("A posicacao 0 do vetor contem o caractere a.");

Se você usar apenas seu nome, sem colchetes o que você obtém já é o endereço de memória do vetor, portanto não é necessário usar o operador &.

Obs: Note que você deve usar o operador & nesse caso: &vetor[2] -> retorna o endereço na memória da segunda posição do vetor (no exemplo acima seria o endereço contendo o caractere 'c' da string).

 

Então observe que nos scanfs do código do @vangodp ele usa o operador & apenas no caso do "fone" (que é uma variável inteira da i-ésima posição da agenda), mas não usa o operador no "nome" nem no "dir", pois são vetores de caracteres.

 

Certo, obrigada pelas explicações, mas me diga uma coisa não entendi especificamente essa linha : 

 scanf ( "%49[^\n]%*c", agenda[i].nome );

O que significa esse  %49 seguido de [^\n]%*c ? 

 

E essa linha também não entendi: 

 scanf ( "%d%*c", &agenda[i].fone );

O %d%*c não entendi, se puder me dar uma explicação detalhada do que significa já sou muito grata desde já! 

Postado

Ok, primeiramente em C o caractere nova linha (=apertar Enter no console) é representado por '\n'.
 
Como você já sabe na string de formatação do scanf são usados especificadores dependendo do tipo de entrada de dados desejado. Todos começando com % seguido do especificador, como %d para inteiro, %c para caractere, %s para string, etc...
 
No caso de caracteres e strings além dos especificadores mencionados acima também é possível usar o especificador %[], este especificador define um conjunto de caracteres que são admitidos como entrada (ou que não são admitidos).
 
Para dizer quais caracteres são admitidos basta digitá-los dentro dos colchetes do especificador. Exs:
 

%[169ab]    -> apenas os caracteres 1, 6, 9, a e b são aceitos%[0-9a-zA-X]  -> são admitidos os caracteres de 0 até 9, de a até z (minúsculo), e de A até X (maiúsculo)

Obs: Note que é possível usar um intervalo de caracteres em sequência usando um hífen.
 
Com este especificador a função scanf obterá, e armazenará no vetor de caracteres, todos caracteres da entrada padrão (standard input) até encontrar um caractere que não esteja na lista de caracteres admissíveis.
 
 
Ao invés de dizer quais caracteres são aceitos, também é possível dizer quais caracteres você não deseja que sejam admissíveis, usando um acento circunflexo '^' após o primeiro colchete ( [^] ). Exs:

%[^a-zA-Z]   -> admite quaisquer caracteres que não sejam letras%[^\n]    -> recebe todos os caracteres até (=exceto) encontrar o caractere nova linha

 
O 49 em %49[^\n] diz número máximo de caracteres a serem lidos/armazenados no vetor de caracteres, pois no código o vetor foi definido com 50 posições, o que implica que o vetor pode armazenar no máximo 49 não nulos, e nesse caso a última posição deverá armazenar o caractere nulo '\0' que indica o fim da string.
 
 
O asterisco * é usado para indicar que o que for obtido por um dado especificador não deverá ser armazenado em uma variável, logo será descartado. Exs:

%*c     -> descarta 1 caractere da entrada padrão%*d     -> descarta 1 número inteiro da entrada padrão

 
Então, juntando tudo isto temos:

%49[^\n]%*c    =  ler/armazenar caracteres até encontrar um caractere nova linha,                   ou até atingir 49 caracteres, mas descartar o caractere nova                  linha (que sempre será o último caractere).%d%*c          = ler um número inteiro, mas descartar o caractere seguinte (nor-                 malmente o caractere nova linha, mas pode ser um espaço)
Postado

Toda ajuda é bem vinda, obrigada eu troquei end por endereço. 

 

 

 

 Isso de não precisar colocar o operador de endereço é somente para strings né? Para inteiros eu coloco normal né? 

 

Eu troquei a palavra end por endereço e tirei os operadores das strings, ainda não funcionou :(

 

Eu utilizo o Dev C++, o que poderia ser mais? 

A declaração de inteiro está errada: int fone[15]; correto int fone;

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