Advertisement
Guest User

Untitled

a guest
Nov 23rd, 2014
131
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. QUESTÃO:
  3.  
  4. Faça um programa em C, usando struct, que armazene registros
  5. em um arquivo contendo informações de uma determinada pessoa.
  6. Saiba que cada registro de pessoa devem existir os campos
  7. código e nome. Os dados devem ser armazenados em arquivos binário.
  8.  
  9. Obs: O programa deverá pedir para o usuário cadastrar uma pessoa e
  10.      somente após inserir as informações no arquivo.
  11.  
  12. COMENTÁRIO:
  13. Certo, pela definição, o programa deverá armazenar em um arquivo binário
  14. os dados de uma determinada pessoa. Tais dados são: código e nome.
  15.  
  16. A forma de como serão salvo os dados da pessoa - citado como "registro de pessoa" -
  17. é de forma pessoal, desde que seja como binário.
  18.  
  19. Entretanto, é necessário que em algum lugar no programa em C, utilize struct.
  20. */
  21.  
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24.  
  25. /*
  26. O nome de uma pessoa é uma string, uma sequência definida de caracteres.
  27. Não faço ideia de onde será usado o programa. Suponho que é no Brasil.
  28. Mas qual o tamanho do nome? Considerar o maior deveria ser a solução.
  29. Entretanto, nomes singulares como do
  30. "Pedro de Alcântara João Carlos Leopoldo Salvador Bibiano Francisco Xavier de Paula Leocádio Miguel Gabriel Rafael Gonzaga"
  31.  - 121 chars - faria o programa necessitar de muito mais memória do que se devia
  32. (Exitem outros maiores¹²)
  33.  
  34. ¹ http://noticias.terra.com.br/educacao/voce-sabia/curiosidades-nomes/
  35. ² http://www.cmjornal.xl.pt/insolitos/detalhe/britanica-adopta-o-maior-nome-do-mundo.html
  36.  
  37. Então, a solução mais fácil seria que nome fosse um ponteiro, e, que o tamanho do nome da pessoa
  38. fosse alocado dinamicamente. Mas, convenhamos, muito trabalho para uma questão escrita
  39. que não tem como nem testar.
  40.  
  41. E o código? CPF? RG? Número atual? Não faço ideia! Como não sei aonde será utilizado,
  42. pouco posso fazer de suposição.
  43. Fechei os olhos e considerei os 4 bytes da geração atual (int).
  44. */
  45. typedef struct {
  46.     char[50] nome;
  47.     int codigo;
  48. } Pessoa;
  49.  
  50. int main() {
  51.     Pessoa pessoa;
  52.    
  53.     printf("Novo cadastro:\n");
  54.     printf("Nome da pessoa:\n");
  55.     scanf("%s", pessoa.nome);
  56.     printf("Código:\n");
  57.     scanf("%d", &pessoa.codigo);
  58.  
  59.     // Append in end of file. Binary mode. Se tiver permissão e o arquivo não existir,
  60.     // este será criado
  61.     File * arquivo = fopen("pessoas.bin", "a+b");
  62.  
  63.     // Sério que, se eu abrir o arquivo como binário o fprintf vai salvar
  64.     fprintf(arquivo, "%s\n", pessoa.nome);
  65.     fprintf(arquivo, "%d\n", pessoa.codigo);
  66.  
  67.     fclose(arquivo);
  68.     return 0;
  69. }
  70.  
  71. /* Então.. não faço ideia de quem irá consumir este dados, se é um programa em C,
  72. e nem se foi compilado pelo gcc.
  73.  
  74. Para não arriscar, criei um padrão: Nome numa linha, código em outra.
  75. Assim, mesmo que o programa se altere e nomes passem a possuir tamanhos diferentes,
  76. quem irá consumir não irar "quebrar".
  77.  
  78. --------------------
  79.  
  80. Mas era só salvar a struct do jeito que está e pronto! Pra quê essa arrumação toda?
  81. R: Além de impossibilitar um possível update, temos uma característica peculiar do compilador gcc,
  82. que é o que utilizamos durante TODO o semestre, as vezes ele adiciona bits sem sentido
  83. entre elementos da struct. É algo tão estranho, que, se trocar a ordem, pode acabar sumindo.
  84. Para desativar isto, temos:
  85. "-fpack-struct"
  86.  
  87. Mas:
  88. 1º Sei disso porque tive um problema lendo uma imagem .BMP no começo do semestre;
  89. 2º Não estudamos isso. Não faço ideia se isso é do gcc ou todo compilador se comporta assim;
  90. 3º Sério, vi isso uns 4 meses atrás, eu ia me lembrar de passar isso?
  91.    Sabia que acontecia, mas não lembrava de como escrevia o comando "-fpack-struct".
  92.  
  93. https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html
  94.  
  95. "-fpack-struct[=n]
  96.  
  97.     Without a value specified, pack all structure members together without holes. When a value is specified (which must be a small power of two), pack structure members according to this value, representing the maximum alignment (that is, objects with default alignment requirements larger than this are output potentially unaligned at the next fitting location.
  98. Warning: the -fpack-struct switch causes GCC to generate code that is not binary compatible with code generated without that switch. Additionally, it makes the code suboptimal. Use it to conform to a non-default application binary interface. "
  99.  
  100.  
  101. ----------
  102.  
  103. E fprintf funciona pra salvar arquivos binários?!?
  104.  
  105. Vejamos primeiro o que "The Programming Language C Ansi - Brian W. Kernighatn and Dennis M. Ritchie"
  106. tem a dizer
  107.  
  108. B.1 Input and Output: <stdio.h>
  109. B.1.1 File Operations
  110.     The following functions deal with operations on files. The type size_t is the unsigned integral type produced by the sizeof operator.
  111.     FILE *fopen(const char *filename, const char *mode)
  112.  
  113. [...] If the mode includes b after the initial letter, as in "rb" or "w+b", that indicates a binary file.
  114.  
  115. [...]
  116.     size_t fwrite(const void *ptr, size_t size, size_t nobj, FILE *stream)
  117. fwrite writes, from the array 'ptr', 'nobj' objects of size 'size' on stream. It returns the
  118. number of objects written, which is less than nobj on error.
  119.  
  120.  
  121. O que dá a entender é que a leitura e a escrita de um arquivo, sendo binário ou não, depende de como tal arquivo é aberto
  122. */
  123.  
  124. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  125. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  126. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  127.  
  128. /* Cabeçalho de arquivo
  129.  * Sobre: informações do arquivo
  130.  * Tamanho: 14 bytes
  131.  */
  132. struct HeadArquivo {
  133.     char bfType[2]; // Nada de \0
  134.     unsigned int bfSize;
  135.     char bfReser1[2];
  136.     char bfReser2[2];
  137.     unsigned int bfOffSetBits;
  138. };
  139.  
  140.  
  141. /* Cabeçalho de mapa de bits
  142.  * Sobre: informações da imagem
  143.  * Tamanho: 40 bytes
  144.  */
  145. struct HeadMapaBits {
  146.     unsigned int biSize;
  147.     unsigned int biWidth;
  148.     unsigned int biHeight;
  149.     unsigned short int biPlanes;
  150.     unsigned short int biBitCount;
  151.     unsigned int biCompress;
  152.     unsigned int biSizeImag;
  153.     unsigned int biXPPMeter;
  154.     unsigned int biYPPMeter;
  155.     unsigned int biClrUsed;
  156.     unsigned int biClrImpor;
  157. };
  158.  
  159. /****************************************
  160.  * Processamento da imagem - Salvar
  161.  ****************************************/
  162. void salvarImagem(const ImagemBMP * const imgBMP, char * const endereco) {
  163.     FILE *imgFile;
  164.  
  165.     imgFile = fopen(endereco, "wb");
  166.  
  167.     fwrite(imgBMP, sizeof(*imgBMP), 1, imgFile);
  168.  
  169.     // Ele grava o endereço da imagem ao invés dos pixels ¬¬"
  170.     //  gambi para sobrescrever o endereço
  171.     fseek(imgFile, -sizeof(imgBMP->pixels), SEEK_END);
  172.     fwrite(imgBMP->pixels, imgBMP->headMapaBits.biSizeImag, 1, imgFile);
  173.  
  174.     fclose(imgFile);
  175. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement