Ir para conteúdo
Fórum Script Brasil
  • 0

(Resolvido) Gravar dados de Struct em Arquivo texto


Flavio_Silva

Pergunta

Boa noite pessoal !
Estou com problemas no código abaixo, pois na minha função Grava_Dados o parâmetro pv_NotaFiscal precisa ser um vetor, dai eu não consigo fazer ele funcionar, alguém poderia me ajudar?

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

struct st_Nota_Fiscal
{
int CodigoNF;
char DT_Emissao[8];
int CodigoCliente;
int QtdeItens;
char CategoriaNota[1];
char TipoFrete[1];
};

enum boolean
{
true = 1, false = 0
}; typedef enum boolean Grava_dados;

Grava_Dados (struct st_Nota_Fiscal pv_NotaFiscal) // O problema é que pv_NotaFiscal precisa ser um vetor e não uma string
{
FILE *fp;
fp = fopen ("NF_010015.txt", "a");
if (fp == NULL)
{
return (false);
exit(1);
}
else
{
fprintf(fp,"%i;%s;%i;%i;%s;%s;\n",pv_NotaFiscal.CodigoNF, pv_NotaFiscal.DT_Emissao, pv_NotaFiscal.CodigoCliente, pv_NotaFiscal.QtdeItens, pv_NotaFiscal.CategoriaNota, pv_NotaFiscal.TipoFrete);

fclose (fp);

return (true);

}
}
int main ()

{
char op;
do{
struct st_Nota_Fiscal dados;
printf ("Digite o Codigo da NF: ");
scanf ("%d", &dados.CodigoNF);
setbuf (stdin, NULL);
printf ("Digite a data da emissao da NF: ");
gets (dados.DT_Emissao);
setbuf (stdin, NULL);
printf ("Digite o codigo do cliente: ");
scanf ("%d", &dados.CodigoCliente);
setbuf (stdin, NULL);
printf ("Digite a quantidade disponivel: ");
setbuf (stdin, NULL);
scanf ("%d", &dados.QtdeItens);
setbuf (stdin, NULL);
printf ("Digite a categoria da NF [V] - Venda ou [T] - Transferencia: ");
gets (dados.CategoriaNota);
setbuf (stdin, NULL);
printf ("Digite o tipo do frete [C] - CIF ou [F] - FOB: ");
gets (dados.TipoFrete);
setbuf (stdin, NULL);

Grava_Dados (dados);
printf ("Deseja gravar mais alguma NF: ");
scanf ("%c", &op);
} while (op == 'S' || op == 's');
return 0;

}

A saída precisa ser separada com " ; ", conforme exemplo:
1;20150410;89;2;V;F
2;20150411;78;1;T;C

Editado por Flavio_Silva
Link para o comentário
Compartilhar em outros sites

2 respostass a esta questão

Posts Recomendados

  • 0

Existem muitas formas de fazer isso:

Aqui deixo uma simples base para que tenha uma noção:

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

struct Estrutura {
    char foo[100];
    int bar;
} umaEstrutura;
typedef struct Estrutura vetor[100];

//funçao que limpa o buffer
void flush_in() {
    int ch;
    while ( ( ch = fgetc ( stdin ) ) != EOF && ch != '\n' ) {}
}

//funçao que abre o arquivo, e si nao for possivel mostra qual foi o erro, funciona igual que fopen
FILE* fileOpen( char* name, char* mode){
    FILE* file = fopen( name, mode);
    if ( file == NULL ){
        perror("Erro: ");
        exit(1);
    }
    return file;
}

//essa funçao salva um a um os dados ao arquivo
void salvarDatos( FILE* arquivo, struct Estrutura* e ){
    fprintf(arquivo,"%s;%d\n",e->foo, e->bar);
} 

int main () {
    FILE* arquivo = fileOpen("Arquivo de provas.txt", "w"); //Por que abrimos primeiro? Por que nao faz sentido ler dados si nao temos um arquivo aberto, simples! =D
    
    vetor v = {0}; // v é um vetor de 100 posiçoes que esta todo iniciado a nulos
    int contador = 0;  // esse contador server para saber quantos registromes temos efetuado, no maximo só pode ser 100, de v[0] a v[99]
    int i = 0;
    char op;
    
    do{ printf( "Escreva uma palavra para foo maximo 100 letras: ");
        scanf("%99s", v[contador].foo); //si a capacidade de foo é de 100 letras só podemos ler 99 ja que a ultima é o nulo e nao devemos usara ultima posiçao, si escrevemos mais de 100 letras o restante fica no buffer, a funçao flush_in se encarga de eliminar a "sobra", resultado é uma leitura segura a prova de transbordamentos de buffer.
        flush_in();
        printf( "Escreva um volor inteiro: ");
        scanf("%d%*c", &v[contador].bar);
        
        //depois de leer uma estrutura devemos incrementar o contador
        contador++;
        
        printf ( "Deseja gravar mais alguma NF: " );
        scanf ( "%c%*c", &op ); // %*c evita que al pulsar a tecla enter, essa mesma tecla vaia parar no buffer(Leitura segura). 
        //repetimos até um maximo de 100 vezes
    } while ( (op == 'S' || op == 's') && contador <= 100 );
    
    //agora porcedemos a guardar...
    for ( i = 0; i<contador; i++ ){
        salvarDatos(arquivo, &v[i]);
    }
    
    //terminado salvamos arquivo
    fclose(arquivo);
    getchar();
    return 0;
}

Si tiver duvidar pergunte, com isso você pode adaptar seu código a esse modelo.

Link para o comentário
Compartilhar em outros sites

  • 0

Boa noite!

Então, devido a minha falta de experiência e mesmo tão bem comentado não consegui entender sua resposta, mais consegui fazer a adaptação necessária conforme segue abaixo:

#include <stdio.h>
#include <stdlib.h>
 
     // um contador global para uso na função principal e booleana
      int cont = 0;
    
     // a struct citada
     struct st_Nota_Fiscal 
     {
           int CodigoNF;
           char DT_Emissao[10];
           int CodigoCliente;
           int QtdeItens;
           char CategoriaNota[1];
           char TipoFrete[1];
    };
 
    // criando a função booleana uma vez que estou trabalhando com c
    enum boolean
    {
          true = 1, false = 0
    }; typedef  enum boolean  Grava_dados;
 
  //a função de gravação com uso do contador global
  Grava_Dados (struct st_Nota_Fiscal pv_NotaFiscal[cont])
  {
         FILE *fp;    
          fp = fopen ("NF_010015.txt", "a");  
          if (fp == NULL)
          {    
               return (false);    
               exit(1);    
          }    
          else
          {    
                // usei o fprintf pois melhor se adaptou a gravação com o vetor pv_NotaFiscal.
                fprintf(fp,"%d;",pv_NotaFiscal[cont].CodigoNF);
                fprintf(fp,"%s;",pv_NotaFiscal[cont].DT_Emissao);
                fprintf(fp,"%d;",pv_NotaFiscal[cont].CodigoCliente); 
                fprintf(fp,"%d;",pv_NotaFiscal[cont].QtdeItens);
                fprintf(fp,"%s;",pv_NotaFiscal[cont].CategoriaNota);
                fprintf(fp,"%s;\n",pv_NotaFiscal[cont].TipoFrete);
                fclose (fp);
                printf ("\n\nDados Gravados com sucesso!\n\n");
          }       
  }
  
  // função principal usei o setbuf apenas para limpar o buffer do teclado e evitar erro na gravação
  int main ()
  {
          char op;
          do{
                struct st_Nota_Fiscal dados[cont];
                printf ("Digite o Codigo da NF: ");
                scanf ("%d", &dados[cont].CodigoNF);
                setbuf (stdin, NULL);
                printf ("Digite a data da emissao da NF [DD/MM/AAAA]: ");
                gets (dados[cont].DT_Emissao);
                setbuf (stdin, NULL);
                printf ("Digite o codigo do cliente: ");
                scanf ("%d", &dados[cont].CodigoCliente);
                setbuf (stdin, NULL);
                printf ("Digite a quantidade disponivel: ");
                setbuf (stdin, NULL);
                scanf ("%d", &dados[cont].QtdeItens);
                setbuf (stdin, NULL);
                printf ("Digite a categoria da NF [V] - Venda ou [T] - Transferencia: ");
                gets (dados[cont].CategoriaNota);
                setbuf (stdin, NULL);
                printf ("Digite o tipo do frete [C] - CIF ou [F] - FOB: ");
                gets (dados[cont].TipoFrete);
                setbuf (stdin, NULL);
                Grava_Dados (dados);
                cont = cont ++;
                printf ("\nDeseja gravar mais alguma NF: ");
                 scanf ("%c", &op);
          } while (op == 'S' || op == 's');
          printf ("\nPrograma finalizado com sucesso\n");
          return 0;
   }

Assim consegui a saída informada.

Agradeço pela atenção, se achar um modo de melhorar pode informar.

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152k
    • Posts
      651,7k
×
×
  • Criar Novo...