Jump to content
Sign in to follow this  
rikardinhuh

problema em structs

Recommended Posts

rikardinhuh

boas, o meu objectivo é tirar as primeiras 3 letras da variavel nome da struct e por na acro para mais tarde fazer login atraves do mesmo :

#define MENU         "##############MENU###############\n"
#define INVALID      "Opcão invalida\n"
#define USERS 4
int registar();
int login();

typedef struct user {
    char nome[20];
    char pass[10];
    char acro[3];
} USER;

int main() {
    int cycle = 0;
    USER id[uSERS];
    int menu_choice;
    int i = 0;
    int user_logado ;


    while (cycle == 0) {
        printf(MENU);
        printf("1. registar   2.Login   3.Sair\n");
        scanf("%d", &menu_choice);
        getchar();
        switch (menu_choice) {
            case 1:
                registar(id, i);

                printf("%s\n", id[i].nome);
                printf("%s\n", id[i].acro);
                printf("%s\n", id[i].pass);
                i++;
                break;
            case 2:
                user_logado = login(id);
                printf("%d", user_logado);
                if (user_logado == 5) {
                    printf(INVALID);
                } else {
                    printf("sucess\n");
                }
                break;

            case 3:
                exit(0);
                break;
            default:
                printf(INVALID);
                break;
        }
    }
    return (EXIT_SUCCESS);
}

int registar(USER *id, int i) {
    printf("%d", i);
    printf("Digite o seu nome:\n");
    scanf("%s",id[i].nome);
    getchar();
    printf("Digite uma pass:\n");
    gets(id[i].pass);

    strncpy(id[i].acro, id[i].nome, 3);




}

só que sempre que faz print do acro nunca aparece direito e nao consigo fazer o login do mesmo... 

(ex: faz-se scanf de ricardo e na acro aparece: ric€5.. )

obrigado ;)

Share this post


Link to post
Share on other sites
newtoncw

Se você der uma olhada na documentação da função strncpy você vai ver que ela não adiciona o caracter null ao final da string, assim sendo, você tem que fazer isso, desta forma, teu código fica assim

char acro[4];
.
.
.
strncpy(id[i].acro, id[i].nome, 3);
id[i].acro[3] = '\0';

Share this post


Link to post
Share on other sites
rikardinhuh

obrigado , realmente resolveu o problema, mas agora deparo-me com um bug ainda mais enervante , quando tento registar outra pessoa o acro "consome" o nome do user anteriormente registado ...

case 3: \\listagem dos users
                for (a = 0; a <= 4; a++) {
                    printf("%s\n", id[a].nome);
                    printf("%s\n", id[a].acro);
                    printf("%s\n", id[a].pass);
                    printf("\n\n");
                }

                break;
...
}

int registar(USER *id, int i) {
    printf("%d", i);
    printf("Digite o seu nome:\n");
    scanf("%s", id[i].nome);
    getchar();
    printf("Digite uma pass:\n");
    gets(id[i].pass);

    strncpy(id[i].acro, id[i].nome, 3);
    id[i].acro[3] = '\0';




}

obrigado mais uma vez ;)

Share this post


Link to post
Share on other sites
Localhost

Podias explicar melhor o último problema que apresentaste? Não percebi bem.

Quanto ao código que deixaste, não utilizes a função gets pois corres o risco de ocorrer um buffer overflow e a variável acro devia ter 4 posições e não 3 visto que o \0 também conta.

Repara:

a[1]    a[2]    a[3]  a[?]

|L|    |O|    |L|    |\0|

Entendeste?


here since 2009

Share this post


Link to post
Share on other sites
rikardinhuh

o que acontece é isto :

probw.jpg

o acro deve ter 3 posiçoes visto que o 0 tambem conta :

a[0]    a[1]    a[2]  a[3]

|L|    |O|      |L|      |\0|

ty

Share this post


Link to post
Share on other sites
bubulindo

o acro deve ter 3 posiçoes visto que o 0 tambem conta :

a[0]    a[1]    a[2]  a[3]

|L|    |O|      |L|      |\0|

ty

Tu acabaste de mostrar que tem de ter 4 posições... em C, a indexação começa no "0", mas a contagem começa no "1". Logo, se queres ter 3 caracteres mais o término, precisas de 4 posições e não 3.

O erro que mostras, parece ser provocado por isso... se definires o vector acro com 3 posições, e assumindo que a memória é linear, quando fazes isto:

id[i].acro[3] = '\0';

Na realidade estás a fazer isto:

id[i+1].nome[0] = '\0'; 

Mas como logo de seguida escreves o nome completo nesse vector, escreves por cima do \0.

Ao usares o printf para ler a string, ele muito provavelmente lê até encontrar o \0... e a julgar pelo que fizeste em cima, o primeiro \0 que encontra é no fim do nome do elemento i+1.

Experimenta, para fins educativos, definir o vector acro com 5 ou 6 posições, mesmo só copiando 3 para ver o que acontece... ou ainda melhor, preenche todas as estruturas manualmente, define um apontador de char para a posição id[0].nome[0] e faz printf de 132 posições sequenciais de memória.

É capaz de ser elucidativo para perceberes isto. :(


include <ai se te avio>

Mãe () {

}

Share this post


Link to post
Share on other sites
Localhost

@bubulindo: isso não funciona bem assim. Se fosse assim tão linear como dizes ele encontraria primeiro o conteúdo da variável pass.

@rikardinhuh: muda aquilo que o @bubulindo indicou e depois mete aqui o resultado.


here since 2009

Share this post


Link to post
Share on other sites
bubulindo

@bubulindo: isso não funciona bem assim. Se fosse assim tão linear como dizes ele encontraria primeiro o conteúdo da variável pass.

Estranho, no meu computador se tentar compilar o código com tamanho 3 no acro recebo um erro... Logo não pude verificar completamente a minha teoria... Mas, ainda assim... este código

	strcpy(id[0].nome, "0000000000000000000");
	strcpy(id[0].pass, "111111111");
	strcpy(id[0].acro, "222");
	strcpy(id[1].nome, "3333333333333333333");
	strcpy(id[1].pass, "444444444");
	strcpy(id[1].acro, "555");
	strcpy(id[2].nome, "6666666666666666666");
	strcpy(id[2].pass, "777777777");
	strcpy(id[2].acro, "888");
	strcpy(id[3].nome, "9999999999999999999");
	strcpy(id[3].pass, "aaaaaaaaa");
	strcpy(id[3].acro, "bbb");
//}
p = &id[0].nome[0];

for(i = 0; i< 124; i++)
{
	printf("%c", *(p+i));
}

Gerou isto...

0000000000000000000


include <ai se te avio>

Mãe () {

}

Share this post


Link to post
Share on other sites
bubulindo

O fórum não gosta quando se coloca as strings com numeros da maneira que coloquei no exemplo do código, mas o que surgiu foi

"0" * 19 + "1"*9 + "2" *3 + "3" * 19 + "4"*9 + "5" *3 + "6" * 19 + "7"*9 + "8" *3 + "9" * 19 + "a"*9 + "b" *3

O que me parece dar razão...

Claro que eu não sou nenhuma autoridade no que toca à organização de memória feita por compiladores, mas a julgar pelo comportamento do programa pareceu-me ser isto que estava a acontecer.

Não percebi como é que do acrónimo do indice 0, ele passava para a pass do indice 1, mas como disse não sou propriamente o mais instruído no que toca a compiladores e organização de memória.


include <ai se te avio>

Mãe () {

}

Share this post


Link to post
Share on other sites
rikardinhuh

funcionou adicionando mais um campo à acro, muito obrigado :(

agora estou com outro dilema, como vou eu desenhar um grafico recorrendo a funçoes da biblioteca stdio.h?

Share this post


Link to post
Share on other sites
bubulindo

Que tipo de gráfico pretendes?

Há um ou dois meses apareceu um post sobre como fazer um gráfico (scatter) usando só printfs... se for de barras também dá. Mas aviso que não é nada doutro mundo.


include <ai se te avio>

Mãe () {

}

Share this post


Link to post
Share on other sites
rikardinhuh

O objectivo era representar graficamente um referencial cartesiano e depois através de uma função inserida pelo user, saber os pontos x e y , para traçar graficamente a função..

Share this post


Link to post
Share on other sites
bubulindo

Nesta thread (http://www.portugal-a-programar.pt/index.php?showtopic=40193) aparece algo desse género, mas a solução é no mínimo limitadíssima. :\

Mas para te ser sincero, e sem ser um expert, não me parece que haja mais possibilidades de fazer um gráfico com a stdio.h. A julgar pelas funções que lá estão definidas (http://www.cplusplus.com/reference/clibrary/cstdio/) é mesmo essa a opção que resta.


include <ai se te avio>

Mãe () {

}

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.