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:

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 ?



Tu peux modifier :
nAttribLength = strlen(sLine)-6;
par
nAttribLength = strlen(sLine)-6 + 1;

et
fprintf(pFileOut, "%s%sn", dataTabString[j].sNum,
dataTabString[j].sAttrib);
par
fprintf(pFileOut, "%s%s", dataTabString[j].sNum, dataTabString[j].sAttrib);

Ca permet de garder le retour chariot dans chaque variable
dataTabString[j].sAttrib
et de le recopier tel quel lors de l'écriture dans le 2ème fichier.
Avatar
Skander Fekih
On 20 juil, 13:19, Christian ASTOR wrote:
programmation wrote:
> 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 ?

Tu peux modifier :
nAttribLength = strlen(sLine)-6;
par
nAttribLength = strlen(sLine)-6 + 1;

et
fprintf(pFileOut, "%s%sn", dataTabString[j].sNum,
dataTabString[j].sAttrib);
par
fprintf(pFileOut, "%s%s", dataTabString[j].sNum, dataTabString[j].sAttrib );

Ca permet de garder le retour chariot dans chaque variable
dataTabString[j].sAttrib
et de le recopier tel quel lors de l'écriture dans le 2ème fichier.



Salut,

Oui. Votre programme çà marche bien. Il permet de supprimer des lignes
vides et des colonnes vides de deuxième champ du fichier.

Comme j'ai dit le fichier d'entrée test.txt est généré
automatiquement. Il est bien formé.
Comme j'ai dit on ne sait pas en avance le nombre des lignes et la
taille de la chaine indication mais cette taille est unique dans tout
le fichier.

je peux savoir le nombre de lignes du fichier et la taille de deuxième
champ.
pour savoir la taille de deuxième champ puis le nombre des lignes des
fichiers j'ai fait successivement :

int main()
{
FILE *pFile, *pFileOut;
char sLine[MAXLINE];
int i,j,k=0,nColumn[32] = {0}, nCpt = 0, nAttribLength= 0,
nMaxAttribLength = 0;
int dataTabStringMax = STEP;
dataStruct *dataTabString;
pFile = fopen("test.txt","r");
pFileOut = fopen("test2.txt","w");

if (pFile && pFileOut)
{
dataTabString = (dataStruct *) malloc(dataTabStringMax
* sizeof(dataStruct));

fgets(sLine, MAXLINE, pFile); //lecture seulement du
première ligne du fichier
sscanf(sLine,"%s%s",dataTabString
[nCpt].sNum,dataTabString[nCpt].sAttrib);
nAttribLength = strlen(dataTabString[nCpt].sAttrib);
printf("%s %s :%dn",dataTabString
[nCpt].sNum,dataTabString[nCpt].sAttrib,nAttribLength);

rewind(pFile); //retourner au début du fichier

while (fgets(sLine, MAXLINE, pFile)) // parcoure tout le
fichier
k++;
printf("%dn",k); // afficher le nombre des lignes du
fichier

rewind(pFile); //retourner au début du fichier

while (fgets(sLine, MAXLINE, pFile))
{
.....
....
}
.....
}

- Quelle est modification à faire dans votre programme pour qu'il
tourne dans tous les cas quelque soit le nombre des lignes du fichier
et la taille de deuxième champ du fichier ?

- Vous mettez #define STEP 10;
10 présente quoi ?

- Vous mettez char sAttrib[32]; et nColumn[32] = {0};
pourquoi vous fixez la taille à 32 ? car on peut avoir la taille de
chaine en général supérieure à 32 ou inférieur à 32 .

- Vous avez alloué et réalloué un tableau

Pouvez m'expliquer le principe d'utilisation d'un tableau avec
réserve et rallouable et car j'ai découvert cette structure avec
vous ? Dans quels cas à utiliser ? les avantages et les limites de
cette structure ?

Merci.
Avatar
Christian ASTOR
Skander Fekih wrote:

- Quelle est modification à faire dans votre programme pour qu'il
tourne dans tous les cas quelque soit le nombre des lignes du fichier
et la taille de deuxième champ du fichier ?



Aucune normalement (tes histoires de rewind, c'est à éviter : il ne faut
pas lire n fois un même fichier, surtout s'il fait des millions de lignes..)
La taille du 2ème champ dépend ici de la longueur de la ligne moins la
taille fixe du premier champ
Le nombre de lignes n'a pas d'importance.

- Vous mettez #define STEP 10;
10 présente quoi ?



Tu le vois bien dans le code : c'est le nombre d'éléments qu'on réalloue
à chaque fois qu'on a atteint le nombre d'éléments max déjà alloués.

- Vous mettez char sAttrib[32]; et nColumn[32] = {0};
pourquoi vous fixez la taille à 32 ? car on peut avoir la taille de
chaine en général supérieure à 32 ou inférieur à 32 .



C'est juste pour l'exemple.
C'est pour définir une taille max pour le 2ème champ.
Tu peux mettre 1000 si tu veux avoir de la marge...

- Vous avez alloué et réalloué un tableau
Pouvez m'expliquer le principe d'utilisation d'un tableau avec
réserve et rallouable et car j'ai découvert cette structure avec
vous ? Dans quels cas à utiliser ? les avantages et les limites de
cette structure ?



Il y a divers sites où c'est mieux expliqué que je ne le ferais
("Dynamic Arrays" dans Google)
Par ex, http://www.utdallas.edu/~rxc064000/dynamicArrays.html
Avatar
programmation
On 20 juil, 15:29, Christian ASTOR wrote:
Skander Fekih wrote:
> - Quelle est  modification à faire dans votre programme pour qu'il
> tourne dans tous les cas quelque soit le nombre des lignes du fichier
> et la taille de deuxième champ du fichier  ?

Aucune normalement (tes histoires de rewind, c'est à éviter : il ne f aut
pas lire n fois un même fichier, surtout s'il fait des millions de lign es..)
La taille du 2ème champ dépend ici de la longueur de la ligne moins l a
taille fixe du premier champ
Le nombre de lignes n'a pas d'importance.

> - Vous mettez #define STEP 10;
> 10 présente quoi ?

Tu le vois bien dans le code : c'est le nombre d'éléments qu'on réa lloue
  à chaque fois qu'on a atteint le nombre d'éléments max déjà alloués.

> - Vous mettez char sAttrib[32]; et nColumn[32] = {0};
> pourquoi vous fixez la taille à 32 ? car on peut avoir la taille de
> chaine en général supérieure à 32 ou inférieur à 32 .

C'est juste pour l'exemple.
C'est pour définir une taille max pour le 2ème champ.
Tu peux mettre 1000 si tu veux avoir de la marge...

> - Vous avez alloué et réalloué un tableau
>  Pouvez m'expliquer le principe d'utilisation d'un tableau avec
> réserve et rallouable et car j'ai découvert cette structure avec
> vous ? Dans quels cas à utiliser ? les avantages et les limites de
> cette structure ?

Il y a divers sites où c'est mieux expliqué que je ne le ferais
("Dynamic Arrays" dans Google)
Par ex,http://www.utdallas.edu/~rxc064000/dynamicArrays.html



Salut,

- Quelle est la différence et l'effet de prendre STEP petit ou
grand ? Est ce que je peux prendre STEP comme la taille maximale de
fichier ?

- Est ce que il y a une fonction définie qui nous donne la taille de
fichier sans le parcourir ?

- C'est possible dans votre programme de sauvegarder les positions
des colonnes supprimées ( c'est à dire les positions dans la chaîne d e
caractère de deuxième champ) car j'ai besoin de ces positions ?
C'est oui. Comment je fasse ? Est ce que je dois utiliser autre
structure ou bien il aura une modification à faire?

- Maintenant, Je voudrais compléter votre programme pour trier ce
fichier résultat obtenu selon le deuxième champ attribut de sorte que
l'objet qui contient de plus de 1 (la carctère 1) dans son attribut
alors il sera placé en premier lieu.
c'est à dire l'attribut qui contient plus de 1 au niveau nombre de
caractère 1.

par exemple:
test.txt:
1 1111
2 1011
3 1111
4 0011
6 1111
7 1111
9 0111
10 1011

il devient après le tri:

1 1111
3 1111
6 1111
7 1111
2 1011
9 0111
10 1011
4 0011

J'ai commencer à faire le programme. Mais, il me manque la partie de
tri.

Voici le programme:

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#define MAXLINE 1024

typedef struct dataStruct
{
int cin;
char indication[32];

} dataStruct;

void main()
{
dataStruct *dataTabString;
FILE *pFile, *pFileOut;
char sLine[MAXLINE];
int nCpt = 0, nAttribLength= 0, nMaxAttribLength = 0,j;
int dataTabStringMax = STEP;
pFile = fopen("essai.txt","r");
pFileOut = fopen("essai2.txt","w");


if (pFile && pFileOut)
{
dataTabString = (dataStruct *) malloc(dataTabStringMax
*sizeof(dataStruct));
while (fgets(sLine, MAXLINE, pFile))
{
sscanf(sLine,"%d%s",&dataTabString
[nCpt].cin,dataTabString[nCpt].indication);


nCpt+=1;
if (nCpt == dataTabStringMax)
{
dataTabStringMax += STEP;
dataTabString = (dataStruct *) realloc
(dataTabString,
dataTabStringMax * sizeof
(dataStruct));
if (dataTabString == NULL)
exit(1);
}
}


// il me manque ici la partie de trier le tableau dataTabString selon
le deuxième champ indication.
// le critère est que l'indication qui possède plus de 1 donc elle
sera en premier ordre et etc.

// remplir le fichier de sortie
for (j = 0; j<nCpt; j++)
{

fprintf(pFileOut, "%-10d%sn",
dataTabString[j].cin,
dataTabString[j].indication);
}

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



Je vous remercie pour votre aide.
Avatar
Christian ASTOR
programmation wrote:

- Quelle est la différence et l'effet de prendre STEP petit ou
grand ? Est ce que je peux prendre STEP comme la taille maximale de
fichier ?



Ca n'a pas de sens, puisque ça revient à un tableau statique.
(si le fichier fait 1 million de lignes, on ne va pas allouer 1 million
d'éléments !)

- Est ce que il y a une fonction définie qui nous donne la taille de
fichier sans le parcourir ?



Pas en nombre de lignes. Et on n'en a pas besoin.

- C'est possible dans votre programme de sauvegarder les positions
des colonnes supprimées ( c'est à dire les positions dans la chaîne de
caractère de deuxième champ) car j'ai besoin de ces positions ?



C'est déjà sauvegardé dans le tableau de compteurs comme déjà expliqué !
Avatar
programmation
On 21 juil, 09:06, Christian ASTOR wrote:
programmation wrote:
> - Quelle est la différence et l'effet de prendre STEP petit ou
> grand  ? Est ce que je peux prendre STEP comme la taille maximale de
> fichier ?

Ca n'a pas de sens, puisque ça revient à un tableau statique.
(si le fichier fait 1 million de lignes, on ne va pas allouer 1 million
d'éléments !)

> - Est ce que il y a une fonction définie qui nous donne la taille de
> fichier sans le parcourir ?

Pas en nombre de lignes. Et on n'en a pas besoin.

> -  C'est possible dans votre programme de sauvegarder les positions
> des colonnes supprimées ( c'est à dire les positions dans la chaî ne de
> caractère de deuxième champ) car j'ai besoin de ces positions ?

C'est déjà sauvegardé dans le tableau de compteurs comme déjà e xpliqué !



Salut,

Je vous remercie pour vos réponses.

- Maintenant, Je voudrais compléter votre programme pour trier ce
fichier résultat obtenu selon le deuxième champ attribut de sorte que
l'objet qui contient de plus de 1 (la carctère 1) dans son attribut
alors il sera placé en premier lieu.
c'est à dire l'attribut qui contient plus de 1 au niveau nombre de
caractère 1.

par exemple, test.txt

1 1111
2 1011
3 1111
4 0011
6 1111
7 1111
9 0111
10 1011

il devient après le tri:

1 1111
3 1111
6 1111
7 1111
2 1011
9 0111
10 1011
4 0011

J'ai fait une fonction de tri rapide d'un tableau en général. Voici
le code:

void échangerÉléments(int t[], int m, int n)
{
int temp = t[m];

t[m] = t[n];
t[n] = temp;
}

int partition(int t[], int m, int n)
{
int v = t[m]; // valeur pivot
int i = m-1;
int j = n+1; // indice final du pivot

while (true) {
do {
j--;
} while (t[j] > v);
do {
i++;
} while (t[i] < v);
if (i<j) {
échangerÉléments(t, i, j);
} else {
return j;
}
}
}

void triRapide(int t[], int m, int n)
{
if (m<n) {
int p = partition(t, m, n);
triRapide(t, m, p);
triRapide(t, p+1, n);
}
}

C'est bon ce tri rapide ? Je vais appeler cette fonction dans le
main.

Mais, il me manque la partie concernant le calcul de nombre de
caractère 1 dans le deuxième champ.
- Est ce que j'ajoute un autre champ dans votre structure qui
présente le nombre de caractère 1 dans le deuxième champ (sAttrib)
pour chaque ligne ?

Voici votre structure:

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

} dataStruct;


- Est ce que j'ajoute une fonction qui permet de calculer le nombre de
caractère 1 dans le deuxième champ ou bien on peut avoir ce nombre
directement à partir de votre programme ?


Merci.
Avatar
Christian ASTOR
programmation wrote:

On 21 juil, 09:06, Christian ASTOR wrote:



2 1011
9 0111
10 1011
4 0011



Comme signalé dans un autre thread, ici avec 1011, 0111, 1011, ça ne
colle pas.

J'ai fait une fonction de tri rapide



Pour les tris, qsort() existe déjà...
Avatar
programmation
On 21 juil, 11:04, Christian ASTOR wrote:
programmation wrote:
> On 21 juil, 09:06, Christian ASTOR wrote:
> 2 1011
> 9 0111
> 10 1011
> 4 0011

Comme signalé dans un autre thread, ici avec 1011, 0111, 1011, ça ne
colle pas.

>  J'ai fait une fonction de tri rapide

Pour les tris, qsort() existe déjà...




Salut,

Ce n'est pas une comparaison binaire. Mais, c'est une comparaison au
niveau le nombre de 1 (le caractère 1).
Si il y a en 4 dans les deux alors on garde le même ordre pour les
deux comme existent dans le fichier.
Par exemple:
2 1011 ici on a trois 1
9 0111 ici on a trois 1
10 1011 ici on a trois 1

Donc dans ce cas on laisse le même ordre. c'est à dire:
2 1011
9 0111
10 1011

Je voudrais faire un tri décroissant qui possède plus de caractere 1
il sera en premier ordre etc .. pour obtenir le résultat suivant:

1 1111
3 1111
6 1111
7 1111
2 1011
9 0111
10 1011
4 0011
Avatar
Christian ASTOR
programmation wrote:

Ce n'est pas une comparaison binaire. Mais, c'est une comparaison au
niveau le nombre de 1 (le caractère 1).



Oui, c'est que j'ai dit : qsort() , avec la fonction de comparaison en
dernier paramètre où l'on fait ce que l'on veut (compter les "1" ou
n'importe quoi d'autre)
Avatar
programmation
On 21 juil, 17:46, Christian ASTOR wrote:
programmation wrote:
> Ce n'est pas une comparaison binaire. Mais, c'est une comparaison au
> niveau le nombre de 1 (le caractère 1).

Oui, c'est que j'ai dit : qsort() , avec la fonction de comparaison en
dernier paramètre où l'on fait ce que l'on veut (compter les "1" ou
n'importe quoi d'autre)



Salut,

- Où est la fonction qsort() ?
- Quelle est la fonction de comparaison ?
1 2 3 4