Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

CamaraoO

scanf ler string

Mensagens Recomendadas

CamaraoO

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "listas.h"

no *username(no *ptr);
int password(no *ptr);




int main(void) {

    no *fst = NULL;

    no *user1 = malloc(sizeof (no));
    user1->prox = NULL;
    user1->user = malloc(sizeof (user));

    user1->user->numec = 8080163;
    user1->user->pass = "password";
    user1->user->nome = "Fabio Teixeira";
    user1->user->tipouser = 3;
    fst = user1;


    no *user2 = malloc(sizeof (no));
    user2->prox = NULL;
    user2->user = malloc(sizeof (user));

    user2->user->numec = 8010672;
    user2->user->pass = "password";
    user2->user->nome = "Antonio Rocha";
    user2->user->tipouser = 3;
    user1->prox = user2;


    no *user3 = malloc(sizeof (no));
    user3->prox = NULL;
    user3->user = malloc(sizeof (user));

    user3->user->numec = 8020326;
    user3->user->pass = "password";
    user3->user->nome = "Tiago Gomes";
    user3->user->tipouser = 3;
    user2->prox = user3;


    no *user4 = malloc(sizeof (no));
    user4->prox = NULL;
    user4->user = malloc(sizeof (user));

    user4->user->numec = 8030934;
    user4->user->pass = "password";
    user4->user->nome = "Barbara Goncalves";
    user4->user->tipouser = 3;
    user3->prox = user4;


    no *user5 = malloc(sizeof (no));
    user5->prox = NULL;
    user5->user = malloc(sizeof (user));

    user5->user->numec = 8040397;
    user5->user->pass = "password";
    user5->user->nome = "Rosanette Cruz";
    user5->user->tipouser = 3;
    user4->prox = user5;


    no *user6 = malloc(sizeof (no));
    user6->prox = NULL;
    user6->user = malloc(sizeof (user));

    user6->user->numec = 8051234;
    user6->user->pass = "password";
    user6->user->nome = "Arnaldo Freitas";
    user6->user->tipouser = 3;
    user5->prox = user6;


    no *user7 = malloc(sizeof (no));
    user7->prox = NULL;
    user7->user = malloc(sizeof (user));

    user7->user->numec = 8060672;
    user7->user->pass = "password";
    user7->user->nome = "Diogo Neves";
    user7->user->tipouser = 1;
    user6->prox = user7;


    no *user8 = malloc(sizeof (no));
    user8->prox = NULL;
    user8->user = malloc(sizeof (user));

    user8->user->numec = 8070427;
    user8->user->pass = "password";
    user8->user->nome = "Marcio Coelho";
    user8->user->tipouser = 3;
    user7->prox = user8;


    no *user9 = malloc(sizeof (no));
    user9->prox = NULL;
    user9->user = malloc(sizeof (user));

    user9->user->numec = 8080007;
    user9->user->pass = "password";
    user9->user->nome = "Luis Branco";
    user9->user->tipouser = 3;
    user8->prox = user9;


    no *user10 = malloc(sizeof (no));
    user10->prox = NULL;
    user10->user = malloc(sizeof (user));

    user10->user->numec = 8090023;
    user10->user->pass = "password";
    user10->user->nome = "Pedro Lobo";
    user10->user->tipouser = 3;
    user9->prox = user10;


    no *user11 = malloc(sizeof (no));
    user11->prox = NULL;
    user11->user = malloc(sizeof (user));

    user11->user->numec = 8090713;
    user11->user->pass = "password";
    user11->user->nome = "Paulo Lopes";
    user11->user->tipouser = 3;
    user10->prox = user11;


    no *user12 = malloc(sizeof (no));
    user12->prox = NULL;
    user12->user = malloc(sizeof (user));

    user12->user->numec = 8010212;
    user12->user->pass = "password";
    user12->user->nome = "Elsa Lopes";
    user12->user->tipouser = 2;
    user11->prox = user12;


    no *user13 = malloc(sizeof (no));
    user13->prox = NULL;
    user13->user = malloc(sizeof (user));

    user13->user->numec = 8020001;
    user13->user->pass = "password";
    user13->user->nome = "Helder Pinto";
    user13->user->tipouser = 2;
    user12->prox = user13;


    no *user14 = malloc(sizeof (no));
    user14->prox = NULL;
    user14->user = malloc(sizeof (user));

    user14->user->numec = 8030028;
    user14->user->pass = "password";
    user14->user->nome = "Ricardo Santos";
    user14->user->tipouser = 2;
    user13->prox = user14;


    password(username(fst));
    
    
}


no *username(no *ptr)
{
    int val;
    
        printf("Introduza o user: ");
        scanf("%d", &val);
    
                while(ptr != NULL){
                        if(val==ptr->user->numec){
    
                                
                                return ptr;
           
                                                 } 
       ptr = ptr->prox;
                                  }
}

int password(no *ptr)
{
    no* aux = malloc(sizeof(no));
    aux->prox = NULL;
    aux->user = malloc(sizeof(user));
    
    printf("Introduza a sua pass: ");
    scanf("%s", aux->user->pass);
    printf("A pass e: %s", aux->user->pass);
}

Tenho os struct das listas num header.

build netbeans:

"/usr/bin/make" -f nbproject/Makefile-Debug.mk QMAKE= SUBPROJECTS= .build-conf

"/usr/bin/make"  -f nbproject/Makefile-Debug.mk dist/Debug/GNU-MacOSX/tp

mkdir -p build/Debug/GNU-MacOSX

rm -f build/Debug/GNU-MacOSX/main.o.d

gcc    -c -g -MMD -MP -MF build/Debug/GNU-MacOSX/main.o.d -o build/Debug/GNU-MacOSX/main.o main.c

mkdir -p dist/Debug/GNU-MacOSX

gcc    -o dist/Debug/GNU-MacOSX/tp build/Debug/GNU-MacOSX/main.o 

BUILD SUCCESSFUL (total time: 271ms)

Alguém me pode dizer porque é que não tá a ler a string que introduzo na função password? :wallbash:

tou farto de pesquisar na net o porque e não encontro...

cumps

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
KTachyon

Será que não está relacionado com os structs?


“There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.”

-- Tony Hoare

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
CamaraoO


typedef struct {
    int numec;
    char *pass;
    char *nome;
    int tipouser;


} user;

typedef struct no {
    user *user;
    struct no *prox;

} no;

Eu acho que não porque consigo imprimir valores lá armazenados...

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
KTachyon

O scanf não faz alocação de memória. Tal como fazes o malloc do nó e do user, tens que alocar memória suficiente para armazenar a pass. O mesmo para o nome.

Também não estás a retornar nada em qualquer uma das funções.


“There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.”

-- Tony Hoare

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
CamaraoO

Já deu muito obrigado  :) !

Então sempre que quiser ler alguma coisa tenho que fazer malloc?

Neste caso antes do scanf faço aux->user->pass = malloc(sizeof(char *)); .

limpar o buffer é com fflush(stdin); ?

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
KTachyon

Então sempre que quiser ler alguma coisa tenho que fazer malloc?

Sim.

Neste caso antes do scanf faço aux->user->pass = malloc(sizeof(char *)); .

Não. Tens que reservar o espaço para a string que pretendes:

aux->user->pass = malloc(sizeof(char)*num_of_chars);

limpar o buffer é com fflush(stdin); ?

Por exemplo, sim.


“There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.”

-- Tony Hoare

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
KTachyon

A função password retorna um int e a função username retorna um ponteiro para um nó. Se não tencionas retornar nada, então colocas void:

void username(no *ptr)

void password(no *ptr)

Para o main já é conveniente retornares qualquer coisa. Nem que seja só meteres no final da função:

return 0;


“There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.”

-- Tony Hoare

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pmg

limpar o buffer é com fflush(stdin); ?

Nao!

A nao ser que pretendas que o teu programa seja unicamente compilavel em Windows.

O Standard de C (onde todos os compiladores para todos os Sistemas Operativos sao baseados) diz claramente que fazer fflush() a um stream de input origina Comportamento Nao Definido.

Por outro lado, o Windows define o comportamento nessas circunstancias (com uma nota meio escondida fazendo notar que o comportamento é uma extensao).

fflush(stdin) clears the contents of the buffer

Uma opcao melhor, no ambito da multi-plataforma, é fazeres a tua propria funcao que "come" os caracteres invalidos do buffer de input.


What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pmg
...
malloc()
...
malloc()
...
malloc()
...

Onde é que estao os free()?


What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
SamLapin

Sinceramente, fiquei um pouco traumatizado com utilizar scanf para ler strings.

O melhor para isso é o fgets. Evita muitos segmentation fault.

fgets seguida de uma limpeza ao buffer claro.

Defines primeiro um buffer com tamanho pré-definido para ler a password. Ves o tamanho da password e no campo password do user alocas só o espaço suficiente para a string que leste.

E reforço o que o utilizar pmg disse. Deve haver um free por cada malloc. Testa sempre os teus programas com o valgrind :)

Cumprimentos

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
aladino77

Sinceramente, fiquei um pouco traumatizado com utilizar scanf para ler strings.

O melhor para isso é o fgets. Evita muitos segmentation fault.

fgets seguida de uma limpeza ao buffer claro.

Defines primeiro um buffer com tamanho pré-definido para ler a password. Ves o tamanho da password e no campo password do user alocas só o espaço suficiente para a string que leste.

E reforço o que o utilizar pmg disse. Deve haver um free por cada malloc. Testa sempre os teus programas com o valgrind ;)

Cumprimentos

Viva!

Duas considerações a fazer.

Primeira, (f)gets/scanf

#define MAX 1024
char b[MAX];
scanf("%s", b); // Lê um conjunto de caracteres nao brancos
fgets(b, MAX - 1, stdin); //Lê uma linha ou até MAX - 1 chars

Segunda, o comportamento de

fflush(stdin); 

é indefinido, ou seja, varia de sistema para sistema ou de implementação para implementação. Uma alternativa portável é desactivar o buffering do stdin.

setvbuf(stdin, (char*)NULL, _IOFBF, 0);

Cumps

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pmg

fgets(b, MAX - 1, stdin); //Lê uma linha ou até MAX - 1 chars

[/code]

O comentário não está coerente com o código. o fgets como tu escreveste lê uma linha com até (MAX - 2) caracteres normais e o '\0'.

O fgets() já conta com o '\0' para o tamanho especificado no segundo argumento. Se, por exemplo, o array tem espaço para 30 caracteres (29 "normais" e o '\0'), podes fazer

fgets(array, 30, stdin)

Reduzir 1 no segundo parametro é desperdiçar um byte :D

É comum ver-se o sizeof e fgets juntos

char buffer[256];
fgets(buffer, sizeof buffer, stdin);


What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.