1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
| #include <stdio.h>
#include <fcntl.h>
#define SZ_TAMPON (32000)
// Taille fichier
unsigned long size_fic(int f)
{
unsigned long size;
unsigned long pos;
// Mémorisation position courante
pos=lseek(f, 0, SEEK_CUR);
// Positionnement fin fichier et récupération taille
size=lseek(f, 0, SEEK_END);
// Repositionnement position initiale
lseek(f, pos, SEEK_SET);
// Renvoi taille trouvée
return size;
}
// Compteur de colonnes
unsigned long cpt_col(int f, char delim)
{
char c;
unsigned long col;
unsigned long pos;
// Mémorisation position courante
pos=lseek(f, 0, SEEK_CUR);
// Rembobinage initial
lseek(f, 0, SEEK_SET);
// Lecture du fichier
col=0;
while (read(f, &c, 1) > 0)
{
// Si on atteint un délimiteur de colonne ou une fin de ligne
if (c == delim || c == '\n')
{
// Une colonne de plus
col++;
// Si on atteint la fin de ligne
if (c == '\n')
// On a fini de compter
break;
}
}
// Repositionnement position initiale
lseek(f, pos, SEEK_SET);
// Renvoi nb colonnes trouvées
return col;
}
// Extraction et écriture d'une colonne X
void write_col(
int f1,
int f2,
unsigned long col,
char delim,
unsigned long size)
{
typedef struct {
char zone[SZ_TAMPON];
char *pt;
int nb;
int i;
} t_buf;
t_buf lire;
t_buf ecrire;
unsigned long nzone;
unsigned long pos;
// Rembobinage initial
lseek(f1, 0, SEEK_SET);
// Itération sur le nb de caractères du fichier
nzone=1;
pos=0;
while (pos < size)
{
// Lecture zone
lire.nb=read(f1, lire.zone, SZ_TAMPON);
// Initialisation zone à écrire
ecrire.pt=ecrire.zone;
ecrire.nb=0;
// Traitement de la zone lue
for (lire.pt=lire.zone, lire.i=0; lire.i < lire.nb; lire.i++, lire.pt++)
{
// La position s'incrémente
pos++;
// Si on a atteint un délimiteur de zone
if (*lire.pt == delim || *lire.pt == '\n')
{
// Le n° de zone augmente
nzone++;
// Si on atteint la fin de la ligne
if (*lire.pt == '\n')
{
// Si on n'est pas à la fin du fichier
if (pos != size)
{
// Stockage délimiteur
*ecrire.pt++=delim;
// Réinitialisation zone pour ligne suivante
nzone=1;
}
else
// Stockage fin de ligne
*ecrire.pt++='\n';
// On a un caractère de plus
ecrire.nb++;
}
// Il ne faut pas stocker le délimiteur
continue;
}
// Si le n° de zone correspond à la colonne demandée
if (nzone == col)
{
// On stocke le caractère
*ecrire.pt++=*lire.pt;
ecrire.nb++;
}
}
// On écrit la zone à écrire
write(f2, ecrire.zone, ecrire.nb);
}
}
int main(int argc, char *argv[])
{
int f1;
int f2;
unsigned long i;
unsigned long ncol;
unsigned long sz_fic;
f1=open(argv[1], O_RDONLY);
f2=open(argv[2], O_WRONLY|O_TRUNC|O_CREAT, 0644);
sz_fic=size_fic(f1);
ncol=cpt_col(f1, '\t');
for (i=1; i <= ncol; i++)
write_col(f1, f2, i, '\t', sz_fic);
close(f1);
close(f2);
} |
Partager