Ol�,

  Fazendo alguns testes, encontrei alguns errinhos e consertei.
  Segue a vers�o 0.2 no corpo da mensagem.
  Deve-se consertar as linhas que foram quebradas para se compilar.


[]'s

Claudio




/************************************************************ * Programa: colunador.c * * Autor: Claudio Polegato Junior * * Data Inicial: 14/08/2001 * * Atualiza��o: 16/03/2005 * * Vers�o: 0.2 * * * * Copyright (C) 2001 por Claudio Polegato Junior * * Todos os direitos reservados * ************************************************************/

/************************************************************
 * Descri��o                                                *
 *                                                          *
 *     Programa para trabalhar com as colunas de um arquivo *
 * texto utilizando-se de colunas com v�rios delimitadores  *
 * e envolvedores de texto na coluna. Cada delimitador      *
 * separa uma coluna da outra e cada linha da entrada deve  *
 * terminar por \n (nova linha).                            *
 *     Este programa requer uma arquivo de entrada (onde -  *
 * especifica stdin, que � a entrada padr�o) e um arquivo   *
 * de sa�da (onde - especifica stdout, que � a sa�da        *
 * padr�o). Seguido destes par�metros obrigat�rios, tem-se  *
 * os opcionais que s�o cada coluna a ser colocada na sa�da *
 * do programa. Caso n�o seja fornecidad nenhuma coluna,    *
 * inverte a ordem de todas as colunas encontradas na       *
 * linha.                                                   *
 *     Os envolvedores de texto s�o validados quando o      *
 * primeiro caracter de uma coluna inicia por ele e o texto *
 * desta coluna vai at� encontrar o caracter correspondente *
 * ao envolvedor final, notado que cada envolvedor inicial  *
 * tem um envolvedor final n�o necessariamente igual ao     *
 * inicial. O texto depois do envolvedor final � ignorado e *
 * o este texto engloba qualquer caracter que n�o seja o    *
 * envolvedor final, inclusive o caracter de nova linha e   *
 * separadores de coluna.                                   *
 *     Existem algumas personaliza��es (at� estou pensando  *
 * em colocar um arquivo de configura��o, por exemplo) que  *
 * podem ser feitas alterando as constantes abaixo. Est�    *
 * bem explicado o significado de cada uma e pode ser usada *
 * a crit�rio das necessidades do momento.                  *
 ************************************************************/

// Defina aqui o separador de colunas na sa�da
// Para manter o mesmo da entrada, deixe-o com '\0'
const char Separador_Saida = '\0';
// Defina aqui o envolvedor de texto da coluna na sa�da (inicial e final)
// Para manter os mesmos da entrada use '\0' e para desaparecer com eles use '\b'
const char Envolvedor_Saida = '"';
const char Envolvedor_Fim_Saida = '"';
// Mude para diferente de zero se quizer todos os textos de cada coluna envolvido pelos envolvedores de texto acima
const int Envolver_Todos = 0;
// Caracteres delimitadores de Coluna
// O espa�o (' ') � interessante para arquivos com colunas que n�o contenham espa�os
// ou cada uma sempre entre aspas
const char Delimitadores[] = {',', ';', '\t'}; // , ' '};
// Caracteres que envolvem um texto completo
const char Envolvedores[] = {'"', '\'', '(', '[', '{', '<'};
const char Envolvedores_Fim[] = {'"', '\'', ')', ']', '}', '>'};



#include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <locale.h>

int Nao_Delimitador(char c){
  int i = 0;
  while (c != Delimitadores[i] && ++i < sizeof(Delimitadores));
  return (i == sizeof(Delimitadores));
}

int Envolvedor(char c){
  int i = 0;
  while (c != Envolvedores[i] && ++i < sizeof(Envolvedores));
  if (i == sizeof(Envolvedores))
    i = -1;
  return i;
}

int main(int argc, char* argv[]){
FILE *Original, *Saida;
int Tamanho, Env, Indice_Coluna;
char *Conteudo, *c, *Coluna[1024];
char Separador[1024];
// Define localiza��o
setlocale(LC_ALL, "");
// Se n�o dados pelo menos o nome do arquivo original e o de sa�da, sai mostrando a forma de uso
if (argc < 3){
fprintf(stderr, "\nUso: %s <arquivo original> <arquivo invertido> [1� Coluna [2� Coluna [...]]]", *argv);
fprintf(stderr, "\n Caso n�o seja informada a ordem das colunas, inverte a ordem.\n\n");
return -1;
}
// Abre o arquivo original e retorna o erro se n�o conseguir
if (strcmp(argv[1], "-")){
Original = fopen(argv[1], "r");
if (! Original){
fprintf(stderr, "\nN�o foi poss�vel ler %s: %s\n\n", argv[1], strerror(errno));
return errno;
}
}
else
Original = stdin;
// Abre e zera ou cria o arquivo de sa�da e retorna o erro se n�o conseguir
if (strcmp(argv[2], "-")){
Saida = fopen(argv[2], "w");
if (! Saida){
fclose(Original);
fprintf(stderr, "\nN�o � poss�vel gravar em %s: %s\n\n", argv[1], strerror(errno));
return errno;
}
}
else
Saida = stdout;
// Tamanho do arquivo original
fseek(Original, 0, SEEK_END);
Tamanho = ftell(Original);
fseek(Original, 0, SEEK_SET);
// Coloca o conte�do do arquivo na mem�ria e fecha o mesmo
Conteudo = (char*)malloc(Tamanho+1);
fread(Conteudo, Tamanho, 1, Original);
Conteudo[Tamanho] = '\0';
fclose(Original);
// Marca as colunas da linha atual separando-as por \0
c = Conteudo;
Indice_Coluna = 0;
while (*c){
Coluna[Indice_Coluna] = c;
if ((Env=Envolvedor(*c)) > -1){
if (Envolvedor_Saida == '\b')
Coluna[Indice_Coluna]++;
else if (Envolvedor_Saida)
*c = Envolvedor_Saida;
c++;
while (*c && *c != Envolvedores_Fim[Env])
c++;
if (Envolvedor_Fim_Saida == '\b')
*(c++) = '\0';
else if (Envolvedor_Fim_Saida)
*(c++) = Envolvedor_Fim_Saida;
}
while (*c && *c != '\n' && Nao_Delimitador(*c))
c++;
if (!*c || *c == '\n'){ // Fim da linha
int i;
*(c++) = '\0';
if (argc == 3){
for (i=Indice_Coluna; i>0; i--){
if (Envolver_Todos && Envolvedor_Saida && Envolvedor_Saida != '\b' && Envolvedor_Saida != *Coluna[i])
fprintf(Saida, "%c", Envolvedor_Saida);
fprintf(Saida, "%s", Coluna[i]);
if (Envolver_Todos && Envolvedor_Fim_Saida && Envolvedor_Fim_Saida != '\b' && Envolvedor_Saida != *Coluna[i])
fprintf(Saida, "%c", Envolvedor_Fim_Saida);
if (Separador_Saida)
fprintf(Saida, "%c", Separador_Saida);
else
fprintf(Saida, "%c", Separador[i]);
}
if (Envolver_Todos && Envolvedor_Saida && Envolvedor_Saida != '\b' && Envolvedor_Saida != *Coluna[0])
fprintf(Saida, "%c", Envolvedor_Saida);
fprintf(Saida, "%s", Coluna[0]);
if (Envolver_Todos && Envolvedor_Fim_Saida && Envolvedor_Fim_Saida != '\b' && Envolvedor_Saida != *Coluna[0])
fprintf(Saida, "%c", Envolvedor_Fim_Saida);
fprintf(Saida, "\n");
}
else{
int Coluna_Atual;
for (i=3; i<argc-1; i++){
Coluna_Atual = atoi(argv[i])-1;
if (Coluna_Atual > Indice_Coluna){
if (Envolver_Todos && Envolvedor_Saida && Envolvedor_Saida != '\b')
fprintf(Saida, "%c", Envolvedor_Saida);
if (Envolver_Todos && Envolvedor_Fim_Saida && Envolvedor_Fim_Saida != '\b')
fprintf(Saida, "%c", Envolvedor_Fim_Saida);
if (Separador_Saida)
fprintf(Saida, "%c", Separador_Saida);
else
fprintf(Saida, "%c", Separador[i-3]);
}
else{
if (Envolver_Todos && Envolvedor_Saida && Envolvedor_Saida != '\b' && Envolvedor_Saida != *Coluna[Coluna_Atual])
fprintf(Saida, "%c", Envolvedor_Saida);
fprintf(Saida, "%s", Coluna[Coluna_Atual]);
if (Envolver_Todos && Envolvedor_Fim_Saida && Envolvedor_Fim_Saida != '\b' && Envolvedor_Saida != *Coluna[Coluna_Atual])
fprintf(Saida, "%c", Envolvedor_Fim_Saida);
if (Separador_Saida)
fprintf(Saida, "%c", Separador_Saida);
else
fprintf(Saida, "%c", Separador[i-3]);
}
}
Coluna_Atual = atoi(argv[argc-1])-1;
if (Envolver_Todos && Envolvedor_Saida && Envolvedor_Saida != '\b' && (Coluna_Atual > Indice_Coluna || Envolvedor_Saida != *Coluna[Coluna_Atual]))
fprintf(Saida, "%c", Envolvedor_Saida);
if (Coluna_Atual <= Indice_Coluna)
fprintf(Saida, "%s", Coluna[Coluna_Atual]);
if (Envolver_Todos && Envolvedor_Fim_Saida && Envolvedor_Fim_Saida != '\b' && (Coluna_Atual > Indice_Coluna || Envolvedor_Saida != *Coluna[Coluna_Atual]))
fprintf(Saida, "%c", Envolvedor_Fim_Saida);
fprintf(Saida, "\n");
}
Indice_Coluna = 0;
}
else{ // Delimitador
Separador[Indice_Coluna] = *c;
*(c++) = '\0';
Indice_Coluna++;
}
}
fclose(Saida);
return 0;
}


---------------------------------------------------------------------------
Esta lista � patrocinada pela Conectiva S.A. Visite http://www.conectiva.com.br

Arquivo: http://bazar2.conectiva.com.br/mailman/listinfo/linux-br
Regras de utiliza��o da lista: http://linux-br.conectiva.com.br
FAQ: http://www.zago.eti.br/menu.html

Responder a