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 | } |