Aide Programme Tri Fichier ordre alphabetique sur codeblock

Résolu/Fermé
ArmaFall - Modifié le 12 janv. 2022 à 00:51
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 - 12 janv. 2022 à 22:28
Bonjour, j'ai un projet en C a réaliser (Mon IDE est codeblock) ou je dois trie un fichier par ordre alphabétique. J'ai donc fait un code, qui fonctionné, cependant j'ai renommer le fichier et potentiellement modifié mon programme et depuis plus rien ne fonctionne. En gros, j'ai l'impression que le programme ne rentre meme pas dans les fonctions (vu que si on fait un test de print nol et noc apres avoir assigné le resultat de ces fontions, le print sera de 1 et -1)
Mon code :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//Liste500niveau1.txt

int comptElementFichier(FILE* fichier){

unsigned int number_of_lines = 0;
int ch;
do{
if ('\n' == ch)
++number_of_lines;
}while ((ch = fgetc(fichier)) != EOF);
return number_of_lines+1;
}

int comptcaraFichier(){
FILE* fichier = NULL;
fichier = fopen("Liste500niveau1.txt", "r+");
int count = 0;
char c;
for (c = fgetc(fichier); c != EOF; c = fgetc(fichier)){
count = count + 1;}
return count-1;
}

int main(){
FILE* fichier = NULL;
FILE* listeTri = NULL;
int caractereActuel = 0;
fichier = fopen("Liste500niveau1.txt", "r+");
listeTri = fopen("listeTri500.txt", "w+");
int nol=0;
int noc=0;
int i=0, j=0, b=0;
char c[100];

nol = comptElementFichier(fichier);
noc = comptcaraFichier(fichier);

rewind(fichier);
char Tabl[nol][noc];
for(i=0;i<nol;i++){
fgets(c, noc, fichier);
strcpy(Tabl[i], c);}

i=0; j=0; b=0;
char wp[100];
for(i=0;i<nol;i++){
for(j=i+1;j<nol-1;j++){

if ( strcmp(Tabl[i], Tabl[j])>0 ){
strcpy(wp, Tabl[i]);
strcpy(Tabl[i], Tabl[j]);
strcpy(Tabl[j], wp);
}
}
}
i=0;
j=0;
for(i=0;i<nol-1;i++){
fprintf(listeTri, "%s" ,Tabl[i]);
}
fclose(fichier);
fclose(listeTri);
}

Merci pour votre aide .
A voir également:

3 réponses

[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
12 janv. 2022 à 14:41
Bonjour ArmaFall,

En exécutant ton code avec un analyseur de mémoire comme valgrind, on a ces résultats :

$ valgrind ./a.out 
==19489== Memcheck, a memory error detector
==19489== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==19489== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==19489== Command: ./a.out
==19489==
==19489== Conditional jump or move depends on uninitialised value(s)
==19489== at 0x1091BC: comptElementFichier (37486791.c:11)
==19489== by 0x1092D0: main (37486791.c:38)
==19489==
==19489==
==19489== HEAP SUMMARY:
==19489== in use at exit: 552 bytes in 1 blocks
==19489== total heap usage: 6 allocs, 5 frees, 13,944 bytes allocated
==19489==
==19489== LEAK SUMMARY:
==19489== definitely lost: 0 bytes in 0 blocks
==19489== indirectly lost: 0 bytes in 0 blocks
==19489== possibly lost: 0 bytes in 0 blocks
==19489== still reachable: 552 bytes in 1 blocks
==19489== suppressed: 0 bytes in 0 blocks
==19489== Rerun with --leak-check=full to see details of leaked memory
==19489==
==19489== For counts of detected and suppressed errors, rerun with: -v
==19489== Use --track-origins=yes to see where uninitialised values come from
==19489== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)


En effet, dans la fonction
int comptElementFichier(FILE* fichier)
, tu n'initialises pas
ch
avant le test.

Essayes en faisant :
int ch = '\0';
.

Si c'est bien la source de tes problèmes, c'est juste une rustine pour permettre à ton code de fonctionner "comme avant".

Cependant, ton code est très peu lisible, plein de maladresses et de choses qui devraient être rectifiées ou faites autrement.

Dal
0
ArmaFall Messages postés 2 Date d'inscription mercredi 12 janvier 2022 Statut Membre Dernière intervention 12 janvier 2022
12 janv. 2022 à 16:17
Bonjour, merci beaucoup pour votre aide, serait-il possible d'avoir quelque exemple ? je suis encore débutant en C
0
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
12 janv. 2022 à 20:03
Une première chose que tu pourrais faire serait d'indenter ton code correctement, cela en facilitera la lecture.

Sinon, voilà quelques observations en vrac et non exhaustives :
  • le type
    size_t
    serait mieux adapté aux variables qui servent à déterminer des tailles ou indices de tableaux (plutôt que
    unsigned int
    )
  • tu fais 3 passes :

1. une en comptant les lignes de ton fichier
2. une en comptant le nombre total de caractères de ton fichier, que tu utilises pour dimensionner la largeur de ton tableau pour chaque ligne (!)
3. une pour lire le contenu dans le tableau, mais dont
fgets()
obtient le contenu dans une variable limitée à une taille de 100 char alors qu'il est permis à fgets() de lire des lignes de la taille du fichier ...
  • dans
    comptElementFichier()
    tu testes le retour de
    fgetc()
    avant d'avoir appelé cette fonction
  • fgetc()
    est très lent, surtout avec ces passes multiples
  • tu rouvres le fichier dans
    comptcaraFichier()
    sans l'avoir fermé
  • tu alloues un tableau VLA potentiellement énorme avec
    char Tabl[nol][noc];
    qui risque d'exploser la capacité de la pile sans que tu puisses le vérifier (surtout que les colonnes sont surdimensionnées si je lis bien ton code)
  • la bibliothèque standard dispose de
    qsort()
  • je pense que tu écris une ligne en moins (à vérifier) en faisant
    for(i=0;i<nol-1;i++){
    ou je ne comprends pas les soustractions que tu fais à cet endroit et à d'autres


Sur les passes.

Si le programme doit traiter n'importe quel fichier texte, quelle que soit la longueur des lignes et leur nombre, tu peux procéder en une passe :
  • soit en réservant toute la mémoire nécessaire à la lecture du fichier d'un coup
  • soit en lisant ligne par ligne avec une taille donnée allouée avec malloc(), que tu modifies avec realloc() en cas de besoin


vois https://stackoverflow.com/questions/29500467/reading-a-line-from-file-in-c-dynamically/29500762#29500762 sur ce sujet.

Si tu veux le faire en 2 passes et ne pas utiliser ces méthodes, tu peux aussi le faire, mais détermine alors dans ta passe préalable (une seule stp) la largeur maximale des lignes et le nombre de lignes à la fois.
0
ArmaFall Messages postés 2 Date d'inscription mercredi 12 janvier 2022 Statut Membre Dernière intervention 12 janvier 2022
12 janv. 2022 à 20:21
Merci beaucoup pour votre aide je vais tester tout ca.
J'ai encore du mal avec indentation, je m'en excuse, c'est vrai que devoir lire du code illisible n'est pas une chose facile.
J'ai vu qu'il exister qsort mais comme c'est un projet d'ecole ou je dois faire des type de tri different (à bulle, selection) , je pense et suis casiment sur que cette fonction est interdite.
Et sinon je vais voir pour tester tout le reste que vous avez proposé.
0
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
12 janv. 2022 à 22:28
Pas de problème, je suis content si mes commentaires peuvent d'aider :-)

Sur l'indentation, un éditeur comme Codeblocks la gère normalement très bien à mesure que tu tapes ton code, et c'est surprenant que tu te retrouves avec un résultat comme celui que tu as posté.

Un EDI comme Codeblocks permet aussi de reformater automatiquement un code.

Tu fais
Plugins - Source code formatter (AStyle)
et cela devrait reformater le code dans le style paramétré dans Codeblocks pour ce plugin.

Tu peux changer ce style dans
Settings - Editor - Source formatter
. Le style le plus classique est le style K&R, qui est tiré de l'ouvrage des créateurs du langage C.
0