Jump to content
Fórum Script Brasil
  • 0

(Resolvido) Gravar dados de Struct em Arquivo texto


Flavio_Silva
 Share

Question

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

Edited by Flavio_Silva
Link to comment
Share on other sites

2 answers to this question

Recommended Posts

  • 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 to comment
Share on other 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 to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

  • Forum Statistics

    • Total Topics
      149.8k
    • Total Posts
      646.6k
×
×
  • Create New...