Ir ao conteúdo

Posts recomendados

Postado

Estou desenvolvendo um código, de cadastro de produtos utilizando arquivos, fiz funções para cadastro, listagem, edição e remoção, o problema está quando tento fazer a edição de um item, cada item tem ID, nome, quantidade e preço, a intenção é manter ID e nome, e alterar a quantidade e preço, porém, quando faço a edição, o nome não se mantém (fica zerado), além do que aparece duplicado os itens, o antigo, com ID, Nome, quantidade e preço, e o editado, com ID, nova quantidade e novo preço.
Aqui estão o código e logo em seguida a imagem do código rodando.

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

FILE *ptrArqProd;

struct produto{
    int id;
    char texto[250];
    int qntd;
    float preco;
};

void cadastraProd();
void consultaProd();
void editaProd();
void removeProd();
void ordenaID();
int contaLinhas();

void criaArquivos() {
  FILE *produtos = fopen("produtos.txt", "r");
  if (produtos == NULL){
    produtos = fopen ("produtos.txt", "w");
    fprintf (produtos,"id-nome-quantidade-preco\n___________________");
   }
  fclose(produtos);
}

void limpaBuffer() {
	int c = 0;
	while ((c = getchar()) != '\n' && c != EOF) {}
	return;
}

int main() {
	criaArquivos(); //verifica se o arquivo produtos.txt ja existe e cria se necessario
    int menu;
    do{
        printf("\nMENU\n(1) Cadastrar produto(s)\n(2) Consultar estoque\n(3) Atualizar produto(s)\n(4) Deletar produto(s)\n(0) Sair\n");
        printf("Acao desejada:");
        scanf("%i", &menu);
        switch(menu){
            case 1:
                cadastraProd();
                break;

            case 2:
                consultaProd();
                break;

            case 3:
                editaProd();
                break;

            case 4:
                removeProd();
                break;

            case 5:
                contaLinhas();
                break;

            case 0:
                printf("\nPrograma finalizado\n");
                break;


            default:
                printf("\nnao tem easteregg aqui\n");
                break;

        }
    } while(menu);

    return 0;
}

void cadastraProd() { //mudar tipo funcao
    char resposta, impressao[22];
    int qntd, cont = 0, linhas = contaLinhas();
    struct produto teste;
    ptrArqProd = fopen("produtos.txt", "a");

    printf("Quantos produtos deseja cadastrar:");
    scanf("%i", &qntd);
    do{
        if(qntd == 1 || cont < qntd)
        fprintf(ptrArqProd, "\n");
        printf("\nDados do produto:\n");
        teste.id = linhas + cont + 1;
        printf("ID: %i", teste.id);
        fprintf(ptrArqProd, "%d-", teste.id);
        printf("\nNome do Produto:");
        scanf("%s",teste.texto);
        fprintf(ptrArqProd, "%s-", teste.texto);
        printf("Quantidade:");
        scanf("%i", &teste.qntd);
        fprintf(ptrArqProd, "%i-", teste.qntd);
        printf("Preco:");
        scanf("%f", &teste.preco);
        fprintf(ptrArqProd, "R$%.2f", teste.preco);
	
        printf("ID: %d     |     Nome do Produto: %s      |     Quantidade: %d     |     Preco: R$%.2f\n", teste.id, teste.texto, teste.qntd, teste.preco);

        fflush(stdin); //PERGUNTAR PROFESSOR
        cont++;
    } while(cont < qntd);

    printf("Deseja cadastrar mais produtos? (s/n) ");
    scanf("%c", &resposta);

    if(resposta != 'n'){
		fclose(ptrArqProd);
    	cadastraProd();
	}

    fclose(ptrArqProd);
    printf("\n");
}

void consultaProd() {
    char impressao[22];

    ptrArqProd = fopen("produtos.txt", "r");

    while(fgets(impressao, 22, ptrArqProd) != NULL){
        printf("%s", impressao);
    }

    printf("\n");

    fclose(ptrArqProd);
}

void editaProd() {
    char impressao[22];
    char id_pesquisa[256];
    int i=0,flag=0,cont=1;
    char teste[22];
    struct produto teste1;
    ptrArqProd = fopen("produtos.txt", "r");
    printf("\nInsira o ID do produto que deseja atualizar: ");
    scanf("%255s",id_pesquisa);

    while(fgets(impressao, 22, ptrArqProd) != NULL){
        for(i=0;i<strlen(impressao);i++){
            if(impressao[i]=='-') break;
            teste[i] = impressao[i];
        }
        teste[i]='\0';
        if(strcmp(teste,id_pesquisa)==0){
            flag = 1;
            break;
        }
        cont++;
    }
    if(flag==0){
        printf("Produto não encontrado");
        return;
    }

    teste1.id = atoi(id_pesquisa);

    printf("Insira a nova quantidade do produto de ID %d : ",teste1.id);
    scanf("%d",&teste1.qntd);

    printf("Insira o novo preco do produto de ID %d : ", teste1.id);
    scanf("%f",&teste1.preco);


    //Removendo a linha, para inserir de novo no arquivo
    FILE *input = fopen("produtos.txt", "r"); //Arquivo de entrada.
    FILE *output = fopen("transferindo.txt", "w"); //Arquivo de saída.
    char texto[1001] = ""; //Uma string larga o suficiente para extrair o texto total de cada linha.
    int linha_selecionada = cont,linha_atual = 1;

    while(fgets(texto, 1001, input) != NULL){
        if(linha_atual != linha_selecionada){
            fputs(texto, output);
        }
        memset(texto, 0, sizeof(char) * 1001);
        linha_atual += 1;
    }
    fclose(ptrArqProd);
    fclose(input);
    fclose(output);

    remove("produtos.txt");
    rename("transferindo.txt", "produtos.txt");
    fflush(stdin); //PERGUNTAR PROFESSOR

    //inserindo novamente a linha editada
    ptrArqProd = fopen("produtos.txt", "a");
    fprintf(ptrArqProd, "\n");
    fprintf(ptrArqProd, "%d-", teste1.id);
    //fprintf(ptrArqProd, "%s-", teste1.texto);
    fprintf(ptrArqProd, "%i-", teste1.qntd);
    fprintf(ptrArqProd, "%.2f", teste1.preco);
    fflush(stdin); //PERGUNTAR PROFESSOR

    printf("Produto editado com sucesso\n");

    fclose(ptrArqProd);
}

void removeProd() {
    char id_pesquisa[256];
    char impressao[22],teste[22];
    int i=0,flag=0,cont=1;
    ptrArqProd = fopen("produtos.txt", "r");

    printf("Insira o ID do produto que deseja remover: ");
    scanf("%255s",id_pesquisa);

    while(fgets(impressao, 22, ptrArqProd) != NULL){
        for(i=0;i<strlen(impressao);i++){
            if(impressao[i]=='-') break;
            teste[i] = impressao[i];
        }
        teste[i]='\0';
        if(strcmp(teste,id_pesquisa)==0){
            flag = 1;
            break;
        }
        cont++;
    }
    
    if(flag != 0) {
    	printf("\n");
    	printf("Produto deletado com sucesso\n");
	}
    
    if(flag==0){
        printf("Produto nao encontrado\n");
        return;
    }

    //Removendo a linha, para inserir de novo no arquivo
    FILE *input = fopen("produtos.txt", "r"); //Arquivo de entrada.
    FILE *output = fopen("transferindo.txt", "w"); //Arquivo de saída.
    char texto[1001] = ""; //Uma string larga o suficiente para extrair o texto total de cada linha.
    int linha_selecionada = cont,linha_atual = 1;

    while(fgets(texto, 1001, input) != NULL){
        if(linha_atual != linha_selecionada){
            fputs(texto, output);
        }
        memset(texto, 0, sizeof(char) * 1001);
        linha_atual += 1;
    }
    fclose(ptrArqProd);
    fclose(input);
    fclose(output);

    remove("produtos.txt");
    rename("transferindo.txt", "produtos.txt");
    fflush(stdin); //PERGUNTAR PROFESSOR
}

int contaLinhas() {
    char impressao[22];
    int i = 0;

    ptrArqProd = fopen("produtos.txt", "r");
    while(fgets(impressao, 22, ptrArqProd) != NULL){
        i++;
    }
    printf("\n");

    fclose(ptrArqProd);
    return (i - 2);
}

 

erro.png

Postado

Eu acho que seria melhor você postar o código completo, por que assim está meio difícil de entender o que está errado.

Postado

 

4 minutos atrás, kgin disse:

Eu acho que seria melhor você postar o código completo, por que assim está meio difícil de entender o que está errado.

Acabei de editar e coloquei o código completo

Postado

Não use funções sem argumentos e retornando void(). É má ideia, proibido em toda parte e só vai trazer problemas. Imagine se seu programa funcionasse, mas aí precisasse de 3 cadastros... 

 

Ia escrever 3 conjuntos de funções diferentes? Use argumentos.

 

Isso que quer fazer se faz usando registros de tamanho fixo para o arquivo... Assim você sabe onde ler e onde gravar depois de atualizar.

Se o arquivo é pequeno em geral se carrega tudo para a memória no início e grava um arquivo novo no fim. Mas pode não ser possível :) 

 

Imagine vários programas acessando o mesmo arquivo: não vai poder carregar na memória do programa.

Imagine se tem milhões de registros, então não vai valer a pena e pode nem ter memória para tanto.

 

O que se faz é a partir do ID achar a posição dele no arquivo, e ler como se fosse um vetor na memória, usando fseek() para posicionar a leitura no lugar certo. Assim não terá problema. 

 

Vai tratar o arquivo em blocos de tamanho igual ao de sua estrutura de produto.

Postado
struct produto{
    int id;
    char texto[250];
    int qntd;
    float preco;
};

 

Como eu te disse, o normal é fazer continhas como se fosse um vetor dessas coisas na memória.

 

Veja esse programa

 

#include <stdio.h>

typedef struct
{
    int     id;
    char    texto[250];
    int     qntd;
    float   preco;

}   Produto;


int main (void)
{
    Produto um;
    Produto outro;
    Produto pdt[500];

    printf("sizeof() = %zd\n", sizeof(Produto));
    return 0;
}

 

Que mostra
 

sizeof() = 264


Isso é o que tem: Produto. Escreva em torno dos dados.

 

Há duas maneiras básicas e nada originais ou novas de fazer isso:

  • um índice. Exemplo: você tem 325 caras no disco então tem um vetor na memória onde na posição X está o id do cara que está na posição X no disco. E na hora de pesquisar busca no vetor, porque é a coisa mais rápida que existe em C. Quer achar o cara de id 123654? vai no vetor e procura. Se estiver na posição 300 do vetor você lê qual registro do disco? o 300 claro. Altera e grava de novo. O 300. Claro. Ao final você pode salvar o índice em um arquivo, ou reconstruir no começo. Registros apagados ficam lá e se preciso pode recompactar o arquivo. Nada especial: cria um novo arquivo com o que sobrou, apaga o antigo e muda o nome do novo.
     
  • uma tabela hash. Muitas linguagens tem isso disponível. mas você faz uma conta com o id e tenta obter um número que vai ser a posição no disco. Uma maneira comum é usar módulo. E cada registro é marcado como usado ou não. E tem que tratar a possibilidade de já estar usado o registro --- se chama colisão --- e ter um tratamento. Avise se quer ir por esse caminho. A performance é muito boa.

Para navegar no arquivo usa fseek() e passa o óbvio: a posição e o nome do arquivo. claro que a posição é a partir do início, 0, e cada elemento vai ocupar sizeof(Produto) então para ler o décimo você se posiciona em 9*sizeof(Produto). O próximo read() vai ler o que? O décimo regisro, se ler apenas o tamanho dele...

 

É mais fácil fazer do que explicar: é so multiplicar. E aí você usa o que pra ler? read(). Para gravar? write(). O simples

 

 

Crie uma conta ou entre para comentar

Você precisa ser um usuário 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 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...

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!