Ir ao conteúdo
  • Cadastre-se
Sioto

Mal funcionamento do fscanf

Recommended Posts

Duvida Simples que está me deixando maluco.

tenho um arquivo que deve ser lido e separado em Modelo do Carro e Preço.

Quando eu uso o fscanf ele Nao está fazendo a separação correta Somente da Primeira linha


cell * insertatbeginning(cell * root,FILE * file){
cell * New, *aux;
aux = root;
New = (cell *) malloc( sizeof(cell) );
if(New == NULL) exit(0);
fscanf(file,"%s%[^R$\n]s", New->model, New->price);
New->next = aux->next;
aux->next = New;
return(aux);
}

então para o meu File contendo as seguintes linhas

D-20 S 3.9/4.0 Turbo Diesel R$64.705,45

Montana Arena 1.4 Econo.Flex 8V 2p R$27.961,91

Corsa GSi 16V R$42.827,36

S10 Blazer DTi 2.8 4x2 Turbo Diesel R$4.902,53

Eu tenho como saida

Nome = D20, preco = S 3.9/4.0 Turbo Diesel

Nome = R$64.705,45 , preco =

Montana Arena 1.4 Econo.Flex 8V 2p (incluindo esse \n mesmo)

Nome = R$27.961,91 , preco =

Corsa GSi 16V

Nome = R$42.827,36 , preco =

S10 Blazer DTi 2.8 4x2 Turbo Diesel

Nome = R$4.902,53 , preco =

Alguem pode ajudar?

ATT

Felipe Sioto Tamburo.

Compartilhar este post


Link para o post
Compartilhar em outros sites
qual o formato da variavel model e price na struct ?

Opa Rafael, desculpa

as duas sao char.

segue o codigo de declaração da struct


typedef struct typedata{
char model[100];
char price[100];
struct cell *next;
} cell;

Compartilhar este post


Link para o post
Compartilhar em outros sites

o fscanf para em espaços ,

cout<<"digite seu nome completo"<<endl;

scanf("%s",&nome);

se eu digitar Rafael Costa , ele só vai pegar o Rafael , acredito que no fscanf seja a mesma coisa

Compartilhar este post


Link para o post
Compartilhar em outros sites

Felipe,

Duvida Simples que está me deixando maluco.

tenho um arquivo que deve ser lido e separado em Modelo do Carro e Preço.

Quando eu uso o fscanf ele Nao está fazendo a separação correta Somente da Primeira linha


cell * insertatbeginning(cell * root,FILE * file){
cell * New, *aux;
aux = root;
New = (cell *) malloc( sizeof(cell) );
if(New == NULL) exit(0);
fscanf(file,"%s%[^R$\n]s", New->model, New->price);
New->next = aux->next;
aux->next = New;
return(aux);
}

então para o meu File contendo as seguintes linhas

Eu tenho como saida

Alguem pode ajudar?

ATT

Felipe Sioto Tamburo.

Não vejo o fscanf() como uma boa opção para resolver esse problema.

O fscanf() não funciona muito bem da forma como usou. Mas entendi o que quis fazer... Ao definir [^R$\n], você diz que a leitura deve parar ao encontrar qualquer um dos caracteres dentro desse conjunto. Ou seja, poderá ser o 'R', o '$' ou o '\n', individualmente. Ele não está casando a string "R$". E isso é um problema sério, pois se o nome do produto contiver um R, ele vai fazer a leitura incorreta das strings.

Baseando-se no seu exemplo dado, tente o seguinte:

fscanf(file, "%[^R] %s\n", New->model, New->price);

Não testei, mas acho que deve retornar o esperado. Note que o nome do produto ainda deve ficar com um espaço no final, pois a leitura será feita exatamente até o primeiro R.

Acho que você poderia fazer a leitura da linha inteira (fgets) e ir trabalhando a string de modo a ter mais precisão com a extração das strings. As estratégias são várias...

[]'s

LNW

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
Felipe,

Não vejo o fscanf() como uma boa opção para resolver esse problema.

O fscanf() não funciona muito bem da forma como usou. Mas entendi o que quis fazer... Ao definir [^R$\n], você diz que a leitura deve parar ao encontrar qualquer um dos caracteres dentro desse conjunto. Ou seja, poderá ser o 'R', o '$' ou o '\n', individualmente. Ele não está casando a string "R$". E isso é um problema sério, pois se o nome do produto contiver um R, ele vai fazer a leitura incorreta das strings.

Baseando-se no seu exemplo dado, tente o seguinte:

fscanf(file, "%[^R] %s\n", New->model, New->price);

Não testei, mas acho que deve retornar o esperado. Note que o nome do produto ainda deve ficar com um espaço no final, pois a leitura será feita exatamente até o primeiro R.

Acho que você poderia fazer a leitura da linha inteira (fgets) e ir trabalhando a string de modo a ter mais precisão com a extração das strings. As estratégias são várias...

[]'s

LNW

LNW, muito obrigado novamente =), funcionou perfeitamente.

Eu tinha pensado nisso que você disse, de usar o fgets e depois pesquisar o $ com o strspn , e o strtok pra quebrar a string em 2.

eu fiz uma pequena adaptação depois que você disse que ele pararia em qualquer R colocando


"%[^$] %s \n"

Agora todos os meus New->model possuem o R no fim da str, então só vou retirar o R utilizando o strlen...

mesmo assim você continua achando uma melhor opcao a de trabalhar com ela toda?

[]

Felipe

Compartilhar este post


Link para o post
Compartilhar em outros sites

Salve Felipe,

LNW, muito obrigado novamente =), funcionou perfeitamente.

Eu tinha pensado nisso que você disse, de usar o fgets e depois pesquisar o $ com o strspn , e o strtok pra quebrar a string em 2.

eu fiz uma pequena adaptação depois que você disse que ele pararia em qualquer R colocando


"%[^$] %s \n"

Agora todos os meus New->model possuem o R no fim da str, então só vou retirar o R utilizando o strlen...

mesmo assim você continua achando uma melhor opcao a de trabalhar com ela toda?

[]

Felipe

Você teria a liberdade para editar esse arquivo de entrada de dados? Se sim, isso facilitaria bastante, pois bastaria tabular aqueles valores e você teria o seu problema resolvido com strtok().

Do jeito como encontra-se o arquivo, não faria muito sentido usar tal função, pois você não dispõe de um separador de valores específico.

Como havia comentado antes, do jeito como está, uma string única contendo dois campos, você vai precisar arrumar alguma estratégia para garantir que ambos os campos serão lidos individualmente.

Por exemplo, se você tem a garantia de que o preço nunca contém nenhum espaço, você poderia fazer uma leitura reversa da string até encontrar o primeiro espaço; encontrado, você já sabe que aquele ponto divide os dois campos da string. Depois, se você quisesse mais precisão, poderia validar a string obtida que representa o preço.

[]'s

LNW

Compartilhar este post


Link para o post
Compartilhar em outros sites
Salve Felipe,

Você teria a liberdade para editar esse arquivo de entrada de dados? Se sim, isso facilitaria bastante, pois bastaria tabular aqueles valores e você teria o seu problema resolvido com strtok().

Do jeito como encontra-se o arquivo, não faria muito sentido usar tal função, pois você não dispõe de um separador de valores específico.

Como havia comentado antes, do jeito como está, uma string única contendo dois campos, você vai precisar arrumar alguma estratégia para garantir que ambos os campos serão lidos individualmente.

Por exemplo, se você tem a garantia de que o preço nunca contém nenhum espaço, você poderia fazer uma leitura reversa da string até encontrar o primeiro espaço; encontrado, você já sabe que aquele ponto divide os dois campos da string. Depois, se você quisesse mais precisão, poderia validar a string obtida que representa o preço.

[]'s

LNW

Fala LNW,

desculpa a demora mais tive de me afastar por uma semaninha.

então cara, eu tinha pensando em usar o seguinte :

Do jeito que você me passou o comando do fgets tava ficando aquele R no fim, então eu pensei nessas duas linhas aqui,


fscanf(file,"%[^$] %s \n", New->model, New->price);
strncpy(aux->model,New->model,strlen(New->model)-1);
strcpy(New->model,aux->model);

porém deu uma zoada nervosa rs,

então to pensando em ler essa string de traz pra frente como tu comentou, mas na net nao achei nada sobre isso.

EDIT :

Esquece rs, consegui fazer essas linhas funcionarem, é que com o strncpy ele nao add o \o no fim então eu fiz


fscanf(file,"%[^$] %s \n", New->model, New->price);
strncpy(aux->model,New->model,strlen(New->model)-2);
aux->model[strlen(New->model)-2] = '\0';
strcpy(New->model,aux->model);

E tudo correu bem =)

de qualquer forma, se tu tiver alguma coisa sobre ler a string de traz pra frente, fiquei interessado haha

administração, caso resolvido =)

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora





Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações 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

×