| Linha | Codigo |
| 001 | // MAC122 - 2017 - Prof. Leo^nidas O. Branda~o |
| 002 | // POLI - Computacao |
| 003 | |
| 004 | // Introducao a leitura/gravacao de arquivos (usando 'fgets') |
| 005 | // Modelo de codigo para leitura de arquivo texto, fazendo um processamento simples e gerando |
| 006 | // como resposta um arquivo HTML. |
| 007 | // Ilustra o funcionamento das funcoes 'strlen(...)' e 'strcpy(...)' da biblioteca "string.h". |
| 008 | |
| 009 | // Para compilar com exame de "estouro" de vetor (e usar padrao o padrao ISO de 1990 para a linguaem C"): |
| 010 | // $ gcc -fsanitize=address -g -std=c99 -o exemplo_processa_arquivo exemplo_processa_arquivo.c |
| 011 | |
| 012 | #include <stdio.h> |
| 013 | #include <stdlib.h> // para 'malloc(...)' |
| 014 | // #include <string.h> // se for usar a funcao 'strcpy(...)' da biblioteca (aqui implementei como 'strcpyNosso(...)')a |
| 015 | |
| 016 | #define MAXLINHAS 100 |
| 017 | #define MAXCOMPLINHA 255 |
| 018 | #define MAXN 60 |
| 019 | |
| 020 | // Variaveis globais para gerar um cabelha e um rodape no arquivo de saida. |
| 021 | // O '\' ao final indica que a linha NAO acabou... |
| 022 | char CABECALHO[] = "<!DOCTYPE html>\ |
| 023 | <html class=\"client-nojs\" lang=\"en\" dir=\"ltr\">\ |
| 024 | <head>\ |
| 025 | <meta charset=\"UTF-8\"/>\ |
| 026 | <title>MAC122 :: modelo para ler/processar/gravar</title>\ |
| 027 | </head>\ |
| 028 | <h3>MAC122 :: modelo para ler/processar/gravar</h3>\ |
| 029 | <font color=\"#0000aa\"><p>Veja os primeiros caracteres das linhas nao vazias do arquivo <tt>%s</tt>.</p></font>\ |
| 030 | <table>\n"; |
| 031 | |
| 032 | char RODAPE[] = "\n</table>\n</body>\n</html>"; |
| 033 | |
| 034 | // Verifica comprimento da linha (codificado de modo compacto) |
| 035 | int strlenNosso (char *strScr) { |
| 036 | int tam = 0; |
| 037 | while (*strScr++) tam++; // pa'ra quando encontrar '\0' (finalizador de "strings" em C) |
| 038 | return tam; |
| 039 | } |
| 040 | |
| 041 | // Copia os caracteres de 'strorig' em 'strdest'. Note que 'strdest' ja TEM que ter espaco alocado! |
| 042 | char *strcpyNosso (char *strdest, const char *strorig) { |
| 043 | char *apont = strdest; |
| 044 | while (*strdest++ = *strorig++) ; // copia caractere a caractere |
| 045 | return apont; // devolva o endereca da "string" que recebeu a copia |
| 046 | } |
| 047 | |
| 048 | // Se linha nao nula, copie um parte inicial e avise tamanho |
| 049 | // senao devolva -1 |
| 050 | int processaLinha (char linha[], char vet[], int conta) { // 'conta' apenas para ajudar depuracao... |
| 051 | int i, j, total = 0; |
| 052 | if (conta==-1) printf("processaLinha: %s\n", linha); // para testes |
| 053 | if (linha[0]=='\0' || linha[0]=='\n') return -1; // linha vazia, nada a fazer... |
| 054 | i = 0; |
| 055 | while (linha[i]==' ' || linha[i]==9) i++; // ignora brancos e TAB = encontra primeiro caracter util (ASCII 9 => TAB) |
| 056 | j = i; |
| 057 | while (linha[j]!='\0' && linha[j]!='\n') j++; // encontrar ultimo caractere (nao final) |
| 058 | if (conta==-1) printf(" (i=%d, j=%d): linha[%d]=%c=%d\n", i, j, j-1, linha[j-1], linha[j-1]); // para testes |
| 059 | vet[total++] = linha[i++]; // copie primeiro caractere |
| 060 | if (i<j) { |
| 061 | vet[total++] = linha[i++]; // havendo, copie segundo |
| 062 | if (i<j) { |
| 063 | vet[total++] = linha[i++]; // havendo, copia terceiro |
| 064 | if (i<j) { |
| 065 | vet[total++] = linha[i++]; // havendo, copia quarto |
| 066 | } |
| 067 | } |
| 068 | } |
| 069 | vet[total] = '\0'; // finaliza "string" |
| 070 | if (conta==-1) printf(" vet=%s\n", vet); |
| 071 | return i; |
| 072 | } |
| 073 | |
| 074 | // Funcao para leitura de arquivo com texto. |
| 075 | // Recebe: 'nomeArqEnt' nome do arquivo e 'vet_nomes' vetor de "strings" para armazenar linhas lidas |
| 076 | // Devolve: numero de caracteres no arquivo |
| 077 | int leitura (char *nomeArqEnt, char vet_nomes[][MAXN]) { |
| 078 | FILE *in_file = fopen(nomeArqEnt, "r"); // read only |
| 079 | char linha[MAXCOMPLINHA]; |
| 080 | int conta = 0, resp; |
| 081 | |
| 082 | if (in_file == NULL) { // Arquivo existe? |
| 083 | printf("Erro! Nao foi possivel abrir o arquivo %s\n", nomeArqEnt); |
| 084 | fclose(in_file); |
| 085 | return -1; |
| 086 | } |
| 087 | printf("---\nInicia leitura do arquivo %s\n", nomeArqEnt); |
| 088 | |
| 089 | conta = 0; |
| 090 | while (1) { // elimina linhas iniciais |
| 091 | if (fgets(linha, MAXCOMPLINHA, in_file)==NULL || ferror(in_file) || feof(in_file) ) // char *fgets(char *str, int n, FILE *stream) |
| 092 | break; // final de arquivo |
| 093 | resp = processaLinha(linha, vet_nomes[conta], conta); |
| 094 | if (resp>0) { // mais uma "substring" copiada! |
| 095 | // printf("%3d : %s", conta, linha); |
| 096 | conta++; |
| 097 | } |
| 098 | } |
| 099 | printf("Total de linhas: %ld\n---\n", conta); |
| 100 | fclose(in_file); |
| 101 | return conta; |
| 102 | } // int leitura(char *nomeArqEnt, char vet_nomes[][MAXN]) |
| 103 | |
| 104 | // Comece por aqui! |
| 105 | // argv[0]="./programa_compara" e demais os argumentos usados |
| 106 | int main (int argc, char **argv) { |
| 107 | char *arq_entra; //[MAXN]; |
| 108 | char arq_saida[MAXN]; |
| 109 | |
| 110 | char vetDados[MAXLINHAS][MAXN]; // ilustrando como pegar trechos do codigo... |
| 111 | |
| 112 | int conta = 0; |
| 113 | int conta_Apolo = 0; |
| 114 | int i, n; |
| 115 | |
| 116 | if (argc < 3) { |
| 117 | printf("Faltaram os nomes dos arquivos de entrada C ou de saida HTML (na verdade NAO esta gravando, para gravar 'descomente' os \\S)\n"); |
| 118 | printf("Linha de comando: ./exemplo_processa_arquivo nome_arquivo.c nome_arquivo.html\n"); |
| 119 | return 1; // faltou um parametro, erro |
| 120 | } |
| 121 | |
| 122 | //D printf("#argc=%d\n", argc); n = argc; for (i=0; i<n; i++) printf(" %d : %s\n", i, argv[i]); |
| 123 | arq_entra = malloc((strlenNosso(argv[1])+1) * sizeof(char)); // printf(" %d : %s\n", strlenNosso(argv[1]), argv[1]); |
| 124 | strcpyNosso(arq_entra, argv[1]); //D printf("arq_entra = %s\n", arq_entra); |
| 125 | |
| 126 | conta = leitura(arq_entra, vetDados); |
| 127 | if (conta<0) { |
| 128 | printf("\nErro na leitura do arquivo %s\n", arq_entra, conta); |
| 129 | return 1; |
| 130 | } |
| 131 | |
| 132 | //D printf("---\nfinal leitura arquivo IME: conta=%d\n", conta); |
| 133 | // Gerar a resposta de processamento (imprimir na tela e gerar novo arquivo) |
| 134 | FILE *out_file = fopen(argv[2], "w"); // "write only" |
| 135 | printf("Lista de primeiros (ate) 4 caracteres de cada linha nao nula\n"); |
| 136 | fprintf(out_file, CABECALHO, arq_entra); |
| 137 | for (i=0; i<conta; i++) { |
| 138 | printf("%3d : %s\n", i, vetDados[i]); |
| 139 | fprintf(out_file, " <tr><td>Linha %3d : </td> <td> %s </td></tr>\n", i, vetDados[i]); |
| 140 | } |
| 141 | fprintf(out_file, RODAPE); |
| 142 | fclose(out_file); |
| 143 | |
| 144 | return 0; |
| 145 | } |