traitement du fichier

Le
programmation
Salut,

J'ai un fichier texte bien formé contient deux champs: objet et
attribut.
tous les objets sont des entiers et tous les attributs sont de chaines
de caractères de même taille.
chaque ligne contient un objet et son attribut par exemple:

essai.txt:

1 11100

2 10101

3 01001

4 10001


Je voudrais supprimer les 0 de même position dans chaque chaine de
caractère.
Par exemple dans notre cas, nous allons supprimer les 0 dans la
position 4 de chaque chaine car dans cette position nous avons toutes
les chaines sont à 0.

le résultat est :


1 1110

2 1011

3 0101

4 1001

j'ai trouvé une difficulté de résoudre ce problème, de plus imagine=
z
si nous avons un fichier volumineux.

SVP, j'ai besoin de vos aides.
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 4
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Christian ASTOR
Le #19701911
programmation wrote:

Je voudrais supprimer les 0 de même position dans chaque chaine de
caractère.
Par exemple dans notre cas, nous allons supprimer les 0 dans la
position 4 de chaque chaine car dans cette position nous avons toutes
les chaines sont à 0.



Par exemple =>

{
DWORD dwFileSize;
DWORD dwBytesRead, dwBytesWritten;;
char *lpBuffer = NULL;
BOOL bStatus = FALSE;
char *sToken;
char sSep[] = "rn";
char sBuffer[255];
HANDLE hFile = CreateFile ("test.txt", GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
HANDLE hFileOut = CreateFile("test2.txt", GENERIC_WRITE,
FILE_SHARE_READ, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE && hFileOut != INVALID_HANDLE_VALUE)
{
dwFileSize = GetFileSize(hFile, NULL);
lpBuffer = (PCHAR)LocalAlloc(LPTR, dwFileSize+1);
if (lpBuffer)
{
bStatus = ReadFile(hFile, lpBuffer, dwFileSize, &dwBytesRead, NULL);
if (bStatus)
{
lpBuffer[dwBytesRead] = 0;
sToken = strtok(lpBuffer, sSep);
while (sToken != NULL)
{
strcpy(sBuffer, sToken);
int nLength = strlen(sBuffer);
memmove(&sBuffer[4], &sBuffer[5], strlen(&sBuffer[5]) + 1);
memcpy (&sBuffer[strlen(sBuffer)], sSep, 2);
sBuffer[nLength + 1] = '';
bStatus = WriteFile(hFileOut, sBuffer, strlen(sBuffer),
&dwBytesWritten, 0);
if (!bStatus)
{
CloseHandle(hFile);
CloseHandle(hFileOut);
if (lpBuffer)
LocalFree(lpBuffer);
return 1;
}
sToken = strtok(NULL, sSep);
}
}
}
CloseHandle(hFile);
CloseHandle(hFileOut);
if (lpBuffer)
LocalFree(lpBuffer);
}
}
Sylvain SF
Le #19701591
programmation a écrit :
Salut,

J'ai un fichier texte bien formé contient deux champs: objet et
attribut.



"contenant" ?

tous les objets sont des entiers et tous les attributs sont de chaines
de caractères de même taille.



des "bitstrings" de même taille ?
(chaîne ne contenant que des '0' et '1')

chaque ligne contient un objet et son attribut par exemple:

essai.txt:
1 11100
2 10101
3 01001
4 10001

Je voudrais supprimer les 0 de même position dans chaque chaine de
caractère.



et quel est le problème ?

j'ai trouvé une difficulté de résoudre ce problème



laquelle ?

de plus imaginez si nous avons un fichier volumineux.



"nous" ?! non, tu as (peut être) un fichier volumineux, moi je
n'aurais que des entiers (possiblement long) à traiter de manière
simple et rapide.

SVP, j'ai besoin de vos aides.



pour faire quoi ?

Sylvain.
Christian ASTOR
Le #19703881
On 6 juil, 08:53, programmation
Pouvez-vous m'expliquer votre idée ?
Quel langage de programmation vous utilisez dans ce code ?



C'est juste du C/Win32 de base..
On lit et charge le fichier dans un buffer puis on découpe les lignes
et on déplace dans chaque ligne de la position 5 à 4 pour supprimer
ton '0'
En C standard, remplace les CreateFile()-ReadFile()-CloseHandle() par
fopen()-fgets()-fclose() en lisant ligne à ligne (ça évite même de
découper par strtok()..)
mdnews
Le #19704501
Sun, 5 Jul 2009 10:48:14 -0700 (PDT), programmation

Salut,

J'ai un fichier texte bien formé contient deux champs: objet et
attribut.
tous les objets sont des entiers et tous les attributs sont de chaines
de caractères de même taille.
chaque ligne contient un objet et son attribut par exemple:

essai.txt:

1 11100

2 10101

3 01001

4 10001


Je voudrais supprimer les 0 de même position dans chaque chaine de
caractère.
Par exemple dans notre cas, nous allons supprimer les 0 dans la
position 4 de chaque chaine car dans cette position nous avons toutes
les chaines sont à 0.

le résultat est :


1 1110

2 1011

3 0101

4 1001

j'ai trouvé une difficulté de résoudre ce problème, de plus imaginez
si nous avons un fichier volumineux.

SVP, j'ai besoin de vos aides.




Pas besoin de programmer, c'est un truc typique pour les expressions
régulières.

Si j'ai bien compris, tu cherches si le chiffre en position 4 est un
zéro et si oui, alors on le supprime ?
Ce qui revient à faire un collage de la partie avant et la partie
après ce zéro s'il existe.

Chercher: (d{3})0(d)
Remplacer par: $1$2

() va mettre en paramètre l'expression trouvé ($1 puis $2)
d signifie chiffre
{3} signifie strictement 3 fois

Avec un éditeur de texte comme EdipadPro (www.jgsoft.com), tu peux
faire cette opération directement. CTRL+F, cocher "Expression
régulière" (on peut cocher "Surligner" pour voir en temps réel si
l'expression régulière est OK) puis cliques sur "tout remplacer"

Beaucoup d'éditeurs ASCII savent chercher par expression régulières,
mais à ma connaissance, c'est le seul qui sait réutiliser le résultat
de la recherche en sortie.

Tu peux faire la même chose avec des petits outils comme SED ou AWK
qui existent en version Windows.
mdnews
Le #19704961
Sun, 5 Jul 2009 10:48:14 -0700 (PDT), programmation

Salut,

J'ai un fichier texte bien formé contient deux champs: objet et
attribut.
tous les objets sont des entiers et tous les attributs sont de chaines
de caractères de même taille.
chaque ligne contient un objet et son attribut par exemple:

essai.txt:

1 11100

2 10101

3 01001

4 10001


Je voudrais supprimer les 0 de même position dans chaque chaine de
caractère.
Par exemple dans notre cas, nous allons supprimer les 0 dans la
position 4 de chaque chaine car dans cette position nous avons toutes
les chaines sont à 0.

le résultat est :


1 1110

2 1011

3 0101

4 1001

j'ai trouvé une difficulté de résoudre ce problème, de plus imaginez
si nous avons un fichier volumineux.

SVP, j'ai besoin de vos aides.




Voila une version en PB (utilisable même avec la version démo)
PB = PureBesic à Télécharger ici
http://www.purebasic.com/french/index.php
tu peux ensuite en faire un EXE autonome
(ne nécessite ni vbrun ni .net ni aucune dll)
Supprimer ou mettre en rem (avec ";") les lignes Debug si tu en fait
un exe autonome (sinon, il ouvrira une fenetre texte)

------------------------------------------------------
ReadFile(0, "essai.txt")
CreateFile(1, "sortie.txt")

; Tant que la fin du fichier n'est pas atteinte
While Not Eof(0)

; Lire une ligne
Ligne$ = ReadString(0)

; Juste pour la vérification: affichage des lignes lues
; dans la fenetre Debug
; tu peux ensuite supprimer toute les lignes commençant par DEBUG
Debug "------------"
Debug Ligne$

; Chercher le premier espace (séparateur de champs)
Position_Espace = FindString(Ligne$, " ", 0)

; Si le quatrième caractère (après l'espace) est un "0"
If Mid(Ligne$, Position_Espace + 4, 1) = "0"

; Extraire le numéro de ligne
Compteur$ = Left(Ligne$, Position_Espace - 1)

; Extraire les 3 caractères après cet espace
Gauche$ = Mid(Ligne$, Position_Espace, 4)

; Extraire les caractères suivants (après le zéro)
; On ne précise pas la longueur
; donc il prend le reste de la chaine
Droite$ = Mid(Ligne$, Position_Espace + 5)

; On recompose la ligne
Nouvelle_Ligne$ = Compteur$ + Gauche$ + Droite$

; Ecriture dans le fichier de sortie
WriteStringN(1, Nouvelle_Ligne$)

; Afficher nouvelle ligne
Debug Nouvelle_Ligne$

EndIf

Wend

CloseFile(0)
CloseFile(1)
programmation
Le #19783131
On 6 juil, 08:16, Christian ASTOR
On 6 juil, 08:53, programmation
> Pouvez-vous m'expliquer votre idée ?
> Quel langage de programmation vous utilisez dans ce code ?

C'est juste du C/Win32 de base..
On lit et charge le fichier dans un buffer puis on découpe les lignes
et on déplace dans chaque ligne de la position 5 à 4 pour supprimer
ton '0'
En C standard, remplace les CreateFile()-ReadFile()-CloseHandle() par
fopen()-fgets()-fclose() en lisant ligne à ligne (ça évite même d e
découper par strtok()..)



Salut,

- Je n'arrive pas à adapter votre solution pour supprimer les
colonnes.
Pouvez-vous me fournir une version en C ?

- J'ai résolu la partie de suppression des lignes. Mais, elle me reste
la partie du suppression des colonnes.

donnée:
Chaque ligne du fichier texte contient deux champs: un objet présenté
par un entier et un attribut présenté par une chaine de caractère.
Le fichier est bien formé puisque il est rempli de manière suivante:
fprintf("%10d%s",objet,attribut);

- Pour la suppression des colonnes, j'ai trouvé une difficulté à
programmer mon idée suivante:
Je positionne sur le premier caractère de chaine de caractère
(deuxième champ) du première ligne du fichier. Je teste caractère par
caractère si égale à 0, par exemple si on trouve 0 à la position k du
la chaine du caractère alors je dois positionner sur la même position
k du la chaine du caractère de deuxième ligne alors je teste si ce
caractère égale à 0 alors je dois positionner sur la même position k
du la chaine du caractère de troisième ligne jusqu'à la fin du
fichier. Dans le cas que si n'est pas égale à 0 alors j'arrête ce
n'est pas la peine de continuer de voir les autres lignes restantes
mais je dois retourner seulement à la position k +1 du chaine du
première ligne pour tester si égale à 0 ou non . Si ce n'est pas ég ale
à 0 alors je teste de même manière les caractères restantes jusqu' à la
fin du ligne.

Autre optimisation, Si je ne trouve aucun 0 dans la chaine du
caractère du première ligne alors c'est inutile de voir les autres
lignes donc on s'arrête et on a aucun colonne à supprimer.
Cette idée permet de trouver les positions à supprimer. Mais, je ne
sais pas comment je vais les supprimer.

Avez-vous une idée ?

S'il vous plait, j'ai besoin de vos aides pour programmer cette idée
et pourquoi pas à améliorer.

Merci.
Christian ASTOR
Le #19783351
programmation wrote:

- Je n'arrive pas à adapter votre solution pour supprimer les
colonnes.
Pouvez-vous me fournir une version en C ?

- J'ai résolu la partie de suppression des lignes. Mais, elle me reste
la partie du suppression des colonnes.



Pour identifier les colonnes ne contenant que des "0", tu peux faire une
première lecture du fichier pour mettre les valeurs (num + attribut)
dans un tableau de structures et utiliser un tableau d'entier pour
compter le nombre de '0' total par colonne : si c'est égal au nombre de
lignes, c'est qu'il n'y a que des "0" dans la colonne donnée.
Ensuite tu lis ton tableau de structures et tu supprimes les "0" pour
chaque position de ton attribut correspondant au compteur précédent
lorsque le compteur est égal au nombre de lignes ("if (nColumn[i] ==
nCpt)" ci-dessous)

Par exemple =>

#include #include <iostream>

#define MAXLINE 1024
#define STEP 10

typedef struct dataStruct
{
char sNum[6];
char sAttrib[32];
} dataStruct;

int _tmain(int argc, _TCHAR* argv[])
{
char sLine[MAXLINE];
int nColumn[32] = {0}, nCpt = 0, nAttribLength= 0, nMaxAttribLength = 0;
FILE *pFile, *pFileOut;
pFile = fopen("test.txt","r");
pFileOut = fopen("test2.txt","w");
int dataTabStringMax = STEP;
dataStruct *dataTabString;
if (pFile && pFileOut)
{
dataTabString = (dataStruct *) malloc(dataTabStringMax *
sizeof(dataStruct));
while (fgets(sLine, MAXLINE, pFile))
{
strncpy(dataTabString[nCpt].sNum, sLine, 5);
dataTabString[nCpt].sNum[5] = '';
nAttribLength = strlen(sLine)-6;
if (nAttribLength>0)
{
strncpy(dataTabString[nCpt].sAttrib, &sLine[5], nAttribLength);
dataTabString[nCpt].sAttrib[nAttribLength] = '';
for (int i = 0; i<nAttribLength; i++)
{
if (dataTabString->sAttrib[i] == '0')
nColumn[i]+=1;
}
nCpt+=1;
if (nAttribLength > nMaxAttribLength)
nMaxAttribLength = nAttribLength;
}
if (nCpt == dataTabStringMax)
{
dataTabStringMax += STEP;
dataTabString = (dataStruct *) realloc(dataTabString,
dataTabStringMax * sizeof(dataStruct));
if (dataTabString == NULL)
exit(1);
}
}
// Lecture tableau de structures pour supprimer les "0"
for (int j = 0; j<nCpt; j++)
{
int nShift = 0;
for (int i = 0; i<nMaxAttribLength; i++)
{
if (nColumn[i] == nCpt)
{
memmove(&dataTabString[j].sAttrib[i-nShift],
&dataTabString[j].sAttrib[i-nShift+1],
strlen(&dataTabString[j].sAttrib[i-nShift+1]) + 1);
nShift+=1;
}
}
if (strcspn (dataTabString[j].sAttrib, "1") <
strlen(dataTabString[j].sAttrib))
fprintf(pFileOut, "%s%sn", dataTabString[j].sNum,
dataTabString[j].sAttrib);
}

free(dataTabString);
fclose(pFile);
fclose(pFileOut);
}
return 0;
}
programmation
Le #19786681
On 19 juil, 02:28, Christian ASTOR
programmation wrote:
> - Je n'arrive pas à adapter votre solution pour supprimer les
> colonnes.
> Pouvez-vous me fournir une version en C ?

> - J'ai résolu la partie de suppression des lignes. Mais, elle me rest e
> la partie du suppression des colonnes.

Pour identifier les colonnes ne contenant que des "0", tu peux faire une
première lecture du fichier pour mettre les valeurs (num + attribut)
dans un tableau de structures et utiliser un tableau d'entier pour
compter le nombre de '0' total par colonne : si c'est égal au nombre de
lignes, c'est qu'il n'y a que des "0" dans la colonne donnée.
Ensuite tu lis ton tableau de structures et tu supprimes les "0" pour
chaque position de ton attribut correspondant au compteur précédent
lorsque le compteur est égal au nombre de lignes ("if (nColumn[i] = =
nCpt)" ci-dessous)

Par exemple =>

#include #include <iostream>

#define MAXLINE 1024
#define STEP 10

typedef struct dataStruct
{
   char sNum[6];
   char sAttrib[32];

} dataStruct;

int _tmain(int argc, _TCHAR* argv[])
{
        char sLine[MAXLINE];
        int nColumn[32] = {0}, nCpt = 0, nAttribLength= 0, nMaxAttribLength = 0;
        FILE *pFile, *pFileOut;
        pFile = fopen("test.txt","r");
        pFileOut = fopen("test2.txt","w");
        int dataTabStringMax = STEP;
        dataStruct *dataTabString;
        if (pFile && pFileOut)
        {
                dataTabString = (dataStruct *) malloc(d ataTabStringMax *
sizeof(dataStruct));
                while (fgets(sLine, MAXLINE, pFile))
                {
                        strncpy(dataTabString[nCp t].sNum, sLine, 5);
                        dataTabString[nCpt].sNum[ 5] = '';
                        nAttribLength = strlen( sLine)-6;
                        if (nAttribLength>0)
                        {
                                strncpy(d ataTabString[nCpt].sAttrib, &sLine[5], nAttribLength);
                                dataTabSt ring[nCpt].sAttrib[nAttribLength] = '';
                                for (int i = 0; i<nAttribLength; i++)
                                {
                                        if (dataTabString->sAttrib[i] == '0')
                                                nColumn[i]+=1;
                                }
                                nCpt+=1 ;
                                if (nAttr ibLength > nMaxAttribLength)
                                        nMaxAttribLength = nAttribLength;
                        }
                        if (nCpt == dataTabSt ringMax)
                        {
                                dataTabSt ringMax += STEP;
                                dataTabSt ring = (dataStruct *) realloc(dataTabString,
                                        dataTabStringMax * sizeof(dataStruct));
                                if (dataT abString == NULL)
                                        exit(1);
                        }
                }
                // Lecture tableau de structures pour sup primer les "0"
                for (int j = 0; j<nCpt; j++)
                {
                        int nShift = 0;
                        for (int i = 0; i<nMaxA ttribLength; i++)
                        {
                                if (nColu mn[i] == nCpt)
                                {
                                        memmove(&dataTabString[j].sAttrib[i-nShift],
&dataTabString[j].sAttrib[i-nShift+1],
strlen(&dataTabString[j].sAttrib[i-nShift+1]) + 1);
                                        nShift+=1;
                                }
                        }
                        if (strcspn (dataTabStrin g[j].sAttrib, "1") <
strlen(dataTabString[j].sAttrib))
                                fprintf(p FileOut, "%s%sn", dataTabString[j].sNum,
dataTabString[j].sAttrib);
                }

                free(dataTabString);
                fclose(pFile);
                fclose(pFileOut);
        }
        return 0;

}



Salut,

- Il manque un accolade fermant qui correspondant à l'accolade ouvert
de if (pFile && pFileOut)
j'ai ajouté cet accolade avant de faire free(dataTabString);
C'est çà ?

- Comme indication, le fichier d'entrée test.txt est construit selon
le format suivant:
fprintf("%10d%sn", sNum,sAttrib);

Donc, je ne sais pas pourquoi vous mettez sNum comme chaine de
caractère et de taille 6 et sAttrib de taille 32
char sNum[6]; et char sAttrib[32]; ?

- Après la compilation et l'exécution de votre code sur le fichier
d'entrée suivant :
test.txt
1 110101
2 100101
3 110101
4 000101
5 000000
6 110101
7 110101
8 000000
9 010101
10 100101

J'obtiens le fichier de sortie test2.txt suivant:
1 1111
2 1011
3 1111
4 0011
6 1111
7 1111
9 0111
10 101

Je ne sais pas pourquoi l'objet 10 lui manque un caractère 1 pour son
attribut.
c-à-d pour l'objet 10 on doit obtenir "1011"

Le résultat attendu est :
test2.txt:
1 1111
2 1011
3 1111
4 0011
6 1111
7 1111
9 0111
10 1011

Donc comment vous obtenez pour 10 l'attribut "1011" ?

- J'ai remarqué que votre dernier programme permet de supprimer des
colonnes mais aussi des lignes vides.
Comment vous avez supprimé des lignes vides par ce dernier programme ?

Merci.
Christian ASTOR
Le #19788371
programmation wrote:

- Il manque un accolade fermant qui correspondant à l'accolade ouvert
de if (pFile && pFileOut)
j'ai ajouté cet accolade avant de faire free(dataTabString);
C'est çà ?



Non, tu as dû mal copier-coller : je viens de re-tester, il ne manque
pas d'accolade. Mais si tu as corrigé et que ça compile, ça va..

- Comme indication, le fichier d'entrée test.txt est construit selon
le format suivant:
fprintf("%10d%sn", sNum,sAttrib);

Donc, je ne sais pas pourquoi vous mettez sNum comme chaine de
caractère et de taille 6 et sAttrib de taille 32
char sNum[6]; et char sAttrib[32]; ?



C'est par rapport à ton fichier d'exemple que j'ai copié-collé:
1 110101
...
=> il y a 6 caractères pour ton Num
Mais c'est à toi de décider du format et donc de changer ce que tu veux.

Je ne sais pas pourquoi l'objet 10 lui manque un caractère 1 pour son
attribut.
c-à-d pour l'objet 10 on doit obtenir "1011"



Parce que tu n'as pas mis de retour chariot après la dernière ligne.

- J'ai remarqué que votre dernier programme permet de supprimer des
colonnes mais aussi des lignes vides.
Comment vous avez supprimé des lignes vides par ce dernier programme ?



Tu le vois en lisant le code lors de la création du 2nd fichier, par la
ligne de test:
if (strcspn (dataTabString[j].sAttrib, "1") <
strlen(dataTabString[j].sAttrib))

Je teste juste s'il y a au moins un "1" dans l'attribut. Si c'est le
cas, on écrit la ligne
programmation
Le #19790221
On 19 juil, 20:01, Christian ASTOR
programmation wrote:

> - Il manque un accolade fermant  qui correspondant à l'accolade ouv ert
> de  if (pFile && pFileOut)
> j'ai ajouté cet accolade avant de faire    free(dataTabString);
> C'est çà ?

Non, tu as dû mal copier-coller : je viens de re-tester, il ne manque
pas d'accolade. Mais si tu as corrigé et que ça compile, ça va..

> - Comme indication, le fichier d'entrée test.txt est construit selon
> le format suivant:
> fprintf("%10d%sn", sNum,sAttrib);

> Donc, je ne sais pas pourquoi vous mettez sNum comme chaine de
> caractère et de taille 6 et sAttrib de taille 32
>   char sNum[6]; et char sAttrib[32]; ?

C'est par rapport à ton fichier d'exemple que j'ai copié-collé:
1    110101
...
=> il y a 6 caractères pour ton Num
Mais c'est à toi de décider du format et donc de changer ce que tu ve ux.

> Je ne sais pas pourquoi l'objet 10 lui manque un caractère 1 pour son
> attribut.
> c-à-d pour l'objet 10 on doit obtenir "1011"

Parce que tu n'as pas mis de retour chariot après la dernière ligne.

> - J'ai remarqué que votre dernier programme permet de supprimer des
> colonnes mais aussi des lignes vides.
> Comment vous avez supprimé des lignes vides par ce dernier programme ?

Tu le vois en lisant le code lors de la création du 2nd fichier, par la
ligne de test:
if (strcspn (dataTabString[j].sAttrib, "1") <
strlen(dataTabString[j].sAttrib))

Je teste juste s'il y a au moins un "1" dans l'attribut. Si c'est le
cas, on écrit la ligne



Salut,

Oui. Il ne manque pas d'accolade.
Oui. Le problème est résolu si on ajoute un retour chariot après la
dernière ligne.

Le fichier test.txt n'est pas saisi à la main. Mais, il est généré
automatiquement. Il est bien formé et comme vous savez la dernière
ligne ne contient pas de retour chariot. Mais, elle contient la marque
de fin du fichier.
Comment on peut résoudre ce problème sans l'ajout du retour chariot
après la dernière ligne ?

S'il vous plaît, il ne manque ce truc. Je n'oublie pas votre aide.

Merci.
Publicité
Poster une réponse
Anonyme