Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

traitement du fichier

38 réponses
Avatar
programmation
Salut,

J'ai un fichier texte bien form=E9 contient deux champs: objet et
attribut.
tous les objets sont des entiers et tous les attributs sont de chaines
de caract=E8res de m=EAme 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=EAme position dans chaque chaine de
caract=E8re.
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 =E0 0.

le r=E9sultat est :


1 1110

2 1011

3 0101

4 1001

j'ai trouv=E9 une difficult=E9 de r=E9soudre ce probl=E8me, de plus imagine=
z
si nous avons un fichier volumineux.

SVP, j'ai besoin de vos aides.

10 réponses

1 2 3 4
Avatar
Christian ASTOR
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);
}
}
Avatar
Sylvain SF
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.
Avatar
Christian ASTOR
On 6 juil, 08:53, programmation wrote:

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()..)
Avatar
mdnews
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.
Avatar
mdnews
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)
Avatar
programmation
On 6 juil, 08:16, Christian ASTOR wrote:
On 6 juil, 08:53, programmation wrote:

> 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.
Avatar
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 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 <tchar.h>
#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;
}
Avatar
programmation
On 19 juil, 02:28, Christian ASTOR wrote:
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 <tchar.h>
#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.
Avatar
Christian ASTOR
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
Avatar
programmation
On 19 juil, 20:01, Christian ASTOR wrote:
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.
1 2 3 4