π
<-

Besoin d'aide pour trouver des erreurs dans du code C

Assembleur, Axe, C/C++, ICE...

Besoin d'aide pour trouver des erreurs dans du code C

Unread postby Bobb » 07 Feb 2022, 18:44

Bonjour à tous,
J'ai commencé à apprendre le C il n'y a pas si longtemps, et débutant que je suis, il m'arrive souvent de faire des erreurs.
En ce moment, je programme des fonctions pour les chaînes de caractères et pour des listes de nombres entiers et de chaines de caractères, dans le but après de les utiliser pour un plus gros programme.
Le problème est que dans ces manipulations de mémoire et de pointeurs, il faut faire attention aux fuites de mémoire etc, et si je ne règle pas tous les problèmes de mes fonctions maintenant, c'est tout mon programme après qui causera plein d'erreurs.

C'est pour ça que j'ai besoin de votre aide.

J'ai testé toutes les fonctions grâce au compilateur MinGW sur Windows 10, et tout fonctionne, mais j'aimerais avoir des conseils de personnes qui s'y connaissent.

Si vous voyez des mauvaises habitudes de programmation dans mon code, ou des choses que je pourrais optimiser, ou des choses à ne pas faire, ou juste si vous avez un commentaire à faire, n'hésiter pas à répondre au topic et à me donner des conseils.

Même si cette démarche de trouver des erreurs dans un code qui n'en présente pas quand on l'exécute peut paraître étrange, je préfère être sûr de partir avec un code propre.

Voici déjà les fonctions de chaînes de caractères :

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <string.h>



void testsFonctions(void);
char* sub(char* string,int debut,int fin);//a liberer après
char* replace(char*, char*, char*);//a liberer après
void cleanStdin(void);
char* addStr(char* str1, char* str2);//a liberer après
long double strToNb(char *string);
char* nbToStr(long double number);//a liberer après
int count(char* string, char* search);
void pause(void);
char* input(char *text);//a libérer après
char* subReplace(char* string, int debut, int longueur, char* remplacement);//à liberer après


int main(void)
{
 
  testsFonctions();
 
  return 0;
}




void testsFonctions(void)
{
 
  //test pour nbToStr
  long double nombre = 16516.5563;
  char* nombrestr=nbToStr(nombre);
  printf("%s\n",nombrestr);
  pause();
 
 
 
 
  //tests pour input et addStr
  char* prenom = input("Quel est votre prenom ? ");
  char* nom = input("Quel est votre nom ? ");
  char* nom_prenom=addStr(addStr(prenom," "),nom);
  printf("Vous vous appelez %s.\n",nom_prenom);
  pause();
  free(nom);free(prenom);
 
 
 
 
  //tests pour sub
  char* chaine="salut les potes";
  char* souschaine=sub(chaine,4,7);
  printf("%s\n",souschaine);
  free(souschaine);
 
 
 
 
  //tests pour replace, nbToStr
  long double nombre2=123456.123;
  printf("%s\n",nbToStr(nombre2));
 
  char* str1 = "01011000101011100010101010100011";
 
  char* str2;
  printf("%s\n",str1);
  str2 = replace(replace(replace(str1,"1","tic"),"0","toc"),"ct","c,t");
  printf("%s\n",str2);
 
  pause();
  free(str2);
 
}





void cleanStdin(void)// vide le buffer
{
    int c = 0;
    while ((c = getchar()) != '\n' && c != EOF);
}



void pause(void)//
{
  printf("\nAppuyez sur une touche pour continuer...");
  cleanStdin();
  //getchar();

}




char* input(char *text)//
{
  char* var=malloc(101*sizeof(char)); // allocation d'un pointeur pour l'entrée de l'utilisateur (+1 char pour le caractère nul)
  if (var==NULL) { exit(-1); }// si l'allocation échoue
 
  memset(var,(char)0,101*sizeof(char));//initialise le pointeur à '\0' partout
 
  //on effectue l'entrée
  printf("%s",text);
  scanf("%100[^\n]",var);
  cleanStdin();
 
  //crée un deuxième pointeur pour y copier le contenu de l'entrée de la vraie longueur
  char* newVar = malloc(sizeof(char)*(strlen(var)+1));//réserve une place de la longueur de l'entrée + 1 pour le caractère nul
  if (newVar==NULL) { exit(-1); }// si l'allocation échoue
 
  memset(newVar,0,sizeof(char)*(strlen(var)+1));//initialise tout à 0
 
  strcpy(newVar,var);//copie de var dans newVar
  free(var);var=NULL;//libération de var
 
  return newVar;
}




int count(char* string, char* search)//compte le nombre d'occurrences d'une chaîne dans une autre
{

int count=0;

  if ( strlen(search) <= strlen(string) )//si la chaîne à rechercher est plus petite que celle dans laquelle on effectue la recherche
  {
    char* tempstr;
    for(int i=0;i<=strlen(string)-strlen(search);i++)
    {
      tempstr=sub(string,i,i+strlen(search)-1);//on va tester la sous chaine de position i
     
      if ( strcmp(search,tempstr)==0 )
      {
        count++;
      }
      free(tempstr);
    }
   
  }
 
 
  return count;
}




char* sub(char* string,int debut,int fin)//permet d'extraire une sous-chaine
{
  int longueur = fin-debut+1;
  char* newStr = malloc(longueur * sizeof(char)+1);//allocation d'un pointeur
  memset(newStr,0,longueur*sizeof(char)+1);//initialisation à 0
  if (newStr==NULL) { exit(-1); }
 
  for (int i=0; i<longueur && i+debut<strlen(string); i++) {//recopie les caractères
    newStr[i]=string[i+debut];
  }
 
  newStr[longueur]='\0';// ajoute je caractère nul
 
  return newStr;
}




char* addStr(char* str1, char* str2)// concatène deux chaines de caractères
{
  char* newStr = malloc(strlen( str1 ) + strlen( str2 ) + 1);
  if (newStr==NULL) { exit(-1); }
 
  strcpy(newStr,str1 );
  strcat(newStr,str2 );

  return newStr;
}




long double strToNb(char *string)//convertit une chaîne de caractère en nombre
{
  long double nombre;
  sscanf(string,"%Lf",&nombre);
  return nombre;
}



char* nbToStr(long double number)//nombre en chaine de caractère
{
  char* strNombre=malloc(50*sizeof(char));//on estime qu'un long double ne fait pas plus de 50 caractères de longueur
  if (strNombre==NULL) { exit(-1); }
  snprintf(strNombre, 50, "%Lf", number);//converison du nombre
 
 
  while (strNombre[strlen(strNombre)-1]=='0')//on enlève les zéros inutiles à la fin
  {
    strNombre[strlen(strNombre)-1]='\0';
  }
 
 
  if (strNombre[strlen(strNombre)-1]=='.')//si on a enlevés tous les zéros, on enlève aussi la virgure
  {
    strNombre[strlen(strNombre)-1]='\0';
  }
 
  return strNombre;
 
}



char* subReplace(char* string, int debut, int longueur, char* remplacement)//effectue un remplacement quand on lui indique l’endroit et la longueur
{
  char* resultat=sub(string,0,debut-1);//prend le début

  resultat=addStr(resultat,remplacement);//ajoute la chaîne de remplacement
 
  resultat=addStr(resultat,sub(string,debut+longueur,strlen(string)-1));//ajoute la fin
   
  return resultat;
}



char* replace(char* string, char* aRemplacer, char* remplacement)//remplace toutes les occurrences d’une chaine par une autre
{
  char* ptrSubStr=0;
  char* tmp;
  while ((ptrSubStr=strstr(string,aRemplacer)) != NULL)//appels successifs a subReplace tant que l’on detecte la chaine a remplacer dans string
  {
    tmp=subReplace(string,(int)ptrSubStr-(int)string,strlen(aRemplacer),remplacement);//enregistrement du résultat dans une chaine temporaire pour pouvoir libérer le contenu pointé par string avant de réaffecter string
   free(string);
   string=tmp;
  }
 
  return string;
}







et voici le retour d'exécution :

Image



Maintenant les fonctions de listes :


Code: Select all
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


char* nbToStr(long double number)//nombre en chaine de caractère
{
  char* strNombre=malloc(50*sizeof(char));//on estime qu'un long double ne fait pas plus de 50 caractères de longueur
  if (strNombre==NULL) { exit(-1); }
  snprintf(strNombre, 50, "%Lf", number);//converison du nombre
 
 
  while (strNombre[strlen(strNombre)-1]=='0')//on enlève les zéros inutiles à la fin
  {
    strNombre[strlen(strNombre)-1]='\0';
  }
 
 
  if (strNombre[strlen(strNombre)-1]=='.')//si on a enlevés tous les zéros, on enlève aussi la virgure
  {
    strNombre[strlen(strNombre)-1]='\0';
  }
 
  return strNombre;
 
}


//définition des structures de listes de nombres et de chaînes de caractères et définition des deux nouveaux types
typedef struct
{
  long long int* tab;
  unsigned len;
 
} intlist;




typedef struct
{
  char** tab;
  unsigned len;
 
} strlist;


//prototypes des fonctions

//intlist
intlist intlist_create(unsigned len);
void intlist_aff(intlist* list);
void intlist_append(intlist* list,long long int nombre);
void intlist_resize(intlist* list, unsigned newLen);
void intlist_remove(intlist* list,unsigned index);


//strlist
strlist strlist_create(unsigned len);
void strlist_aff(strlist* list);
void strlist_append(strlist* list, char *chaine);
void strlist_resize(strlist* list, unsigned newLen);
void strlist_remove(strlist* list,unsigned index);






int main(void)
{
  //contient les tests
 
  intlist maListe=intlist_create(0);//crée une liste de taille zéro
 
  intlist_aff(&maListe);// affiche la liste
 
  for (unsigned i=0;i<14;i++)// ajoute des éléments
    intlist_append(&maListe,(long long int)i);

  intlist_aff(&maListe);// affiche la liste
 
  intlist_resize(&maListe, maListe.len+5);// ajoute 5 éléments à la taille actuelle
  intlist_aff(&maListe);// affiche
 
  intlist_remove(&maListe,0);// supprime le premier élément
  intlist_aff(&maListe);// affiche la liste
 
  /*****************************************/
 
  strlist maListestr=strlist_create(0);//crée une liste de taille zéro
  strlist_aff(&maListestr);// affiche la liste
 
  for (unsigned i=0;i<14;i++)// ajoute des éléments
    strlist_append(&maListestr,nbToStr(15-i));

  strlist_aff(&maListestr);// affiche la liste
 
  strlist_resize(&maListestr, maListestr.len-5);// enlève 5 éléments à la taille actuelle
  strlist_aff(&maListestr);// affiche
 
  strlist_remove(&maListestr,0);// supprime le premier élément
  strlist_aff(&maListestr);// affiche la liste

 
 
  return 0;
}




//intlist

intlist intlist_create(unsigned len)// crée une liste d'entiers
{
  intlist list;//crée la structure
  list.tab=malloc(len*sizeof(long long int));//initialise le tableau de longueur len avec de zéros
  if (list.tab==NULL) {exit(-1);}
  memset(list.tab,0,len);
 
  list.len=len;//initialise la bonne longueur
  return list;//retourne la structure
}




void intlist_aff(intlist* list)//affiche une liste d'entiers
{
  if (list->len == 0)//si la liste a une longueur de zéro
  {
    printf("[]\n");
  }
  else
  {
    printf("[");
    for ( unsigned i = 0 ; i < list->len -1 ; i++)//affiche les éléments du premier à l'avant-dernier
      printf("%lli, ",list->tab[i]);
 
    printf("%lli]\n",list->tab[list->len-1]);//affiche le dernier élément
  }
}




void intlist_append(intlist* list,long long int nombre)//ajoute un élément à la fin de la liste
{
  long long int *tmp = realloc(list->tab, (list->len+1)*sizeof(long long int));//réallocation de list.tab
  if (tmp == NULL){exit(-1);}

  list->tab = tmp;//affectation du pointeur de tmp vers list.tab

  list->tab[list->len]=nombre;//affecte nombre au dernier élément
  list->len++;//incrémente la longueur
}



void intlist_resize(intlist* list, unsigned newLen)//redimensionne la liste avec la nouvelle longueur
{
  long long int *tmp = realloc(list->tab, newLen*sizeof(long long int));//réalloue un pointeur de la nouvelle taille

  if (tmp == NULL){exit(-1);}

  list->tab = tmp;
 
  if (newLen > list->len)//initialisation des nouveaux éléments à 0 si nouveaux éléments il y a
  {
    for (unsigned i = list->len ; i < newLen ; i++)
     list->tab[i]=0;
  }
 
  list->len=newLen;//modification de la longueur
 
}





void intlist_remove(intlist* list,unsigned index)//supprime un élément de la liste
{
  for (unsigned i = index ; i < list->len -1; i++)//décale tous les éléments à partir de celui à supprimer
    list->tab[i]=list->tab[i+1];
 
  long long int *tmp = realloc(list->tab, (list->len-1)*sizeof(long long int));//réalloue un nouveau pointeur de la bonne taille

  if (tmp == NULL){exit(-1);}

  list->tab = tmp;
 
  list->len--;//décrémentation de la longueur
 
}







//strlist


strlist strlist_create(unsigned len)
{
  strlist list;
  list.tab=malloc(len*sizeof(char*));
  if (list.tab==NULL) {exit(-1);}
  memset(list.tab,0,len);
  list.len=len;
  return list;
}





void strlist_aff(strlist* list)
{
  if (list->len == 0)
  {
    printf("[]\n");
  }
  else
  {
    printf("[");
    for ( int i = 0 ; i < list->len -1 ; i++)
      (list->tab[i]==NULL) ? printf("\"\", ") : printf("\"%s\", ",list->tab[i]);//affiche "" si le pointeur est nul
 
 
   (list->tab[list->len-1]==NULL) ? printf("\"\"]\n") : printf("\"%s\"]\n",list->tab[list->len-1]);//dernier élément
  }
}




void strlist_append(strlist* list, char *chaine)
{
  char **tmp = realloc(list->tab, (list->len+1)*sizeof(char*));

  if (tmp == NULL){exit(-1);}

  list->tab = tmp;

  list->tab[list->len]=chaine;
  list->len++;
}




void strlist_resize(strlist* list, unsigned newLen)
{
 
  //il faut au préalable libérer les éléments qui vont être tronqués si la nouvelle longueur est plus petite
  if (newLen < list->len)
  {
      for (unsigned i = newLen ; i < list->len ; i++)
       free(list->tab[i]);
  }
 
 
  char **tmp = realloc(list->tab, newLen*sizeof(char*));
  if (tmp == NULL){exit(-1);}

  list->tab = tmp;
 
 
  if (newLen > list->len)//on initialise les nouveaux elements si nouveaux elements il y a
  {
    for (unsigned i = list->len ; i < newLen ; i++)
     list->tab[i]=(char*)0;
  }
 
  list->len=newLen;
 
}



void strlist_remove(strlist* list,unsigned index)
{
  for (unsigned i = index ; i < list->len -1; i++)
    list->tab[i]=list->tab[i+1];
 
  free(list->tab[list->len]);
 
  char **tmp = realloc(list->tab, (list->len-1)*sizeof(char*));
  if (tmp == NULL){exit(-1);}
 
  list->tab = tmp;
  list->len--;
 
}





Le retour d'exécution :
Image

Merci de votre contribution,
Bobb
Last edited by Bobb on 07 Feb 2022, 19:20, edited 2 times in total.

Tous mes programmes sont disponibles ici

↳ Testez mon simulateur Android sur Ti-83 Premium CE et / ou Édition Python
Jetez un coup d'oeil à mon langage de programmation interprété Neon.

Image
User avatar
BobbProgrammeur
Niveau 11: LV (Légende Vivante)
Niveau 11: LV (Légende Vivante)
Level up: 0.7%
 
Posts: 322
Joined: 19 Apr 2020, 12:37
Location: Morbihan
Gender: Male
Calculator(s):
MyCalcs profile
Class: ENS Rennes info

Re: Besoin d'aide pour trouver des erreurs dans du code C

Unread postby Adriweb » 07 Feb 2022, 19:05

J'ai juste parcouru tres rapidement le code, et je vois que tu définis la fonction "subReplace" à l'intérieur d'une autre fonction ! Ca c'est pas bon, tu as de la chance que ca marche, c'est une extension spéciale du compilateur gcc. Déplace la uste au dessus, par exemple.
As-tu utilisé des outils d'analyse statique ? genre cppcheck.
Par ailleurs, essaye un IDE genre Clion, c'est gratuit pour les etudiants :) (et sinon trial) Il t'aidera pas mal, voire trouvera des choses à améliorer/corriger dans ton code.

Sur Windows ca risque d'etre compliqué, mais sinon pour les fuites et comportements pas normaux, ASAN et Valgrind sont des bons amis à avoir...

MyCalcs: Help the community's calculator documentations by filling out your calculators info!
MyCalcs: Aidez la communauté à documenter les calculatrices en donnant des infos sur vos calculatrices !
Inspired-Lua.org: All about TI-Nspire Lua programming (tutorials, wiki/docs...)
My calculator programs
Mes programmes pour calculatrices
User avatar
AdriwebAdmin
Niveau 16: CC2 (Commandeur des Calculatrices)
Niveau 16: CC2 (Commandeur des Calculatrices)
Level up: 79.7%
 
Posts: 14817
Images: 1131
Joined: 01 Jun 2007, 00:00
Location: France
Gender: Male
Calculator(s):
MyCalcs profile
Twitter: adriweb
GitHub: adriweb

Re: Besoin d'aide pour trouver des erreurs dans du code C

Unread postby Bobb » 07 Feb 2022, 19:22

OK, c'est bon,j'ai changé subReplace.
Sinon, merci pour tous les outils je testerai un peu tout ça.

Tous mes programmes sont disponibles ici

↳ Testez mon simulateur Android sur Ti-83 Premium CE et / ou Édition Python
Jetez un coup d'oeil à mon langage de programmation interprété Neon.

Image
User avatar
BobbProgrammeur
Niveau 11: LV (Légende Vivante)
Niveau 11: LV (Légende Vivante)
Level up: 0.7%
 
Posts: 322
Joined: 19 Apr 2020, 12:37
Location: Morbihan
Gender: Male
Calculator(s):
MyCalcs profile
Class: ENS Rennes info

Re: Besoin d'aide pour trouver des erreurs dans du code C

Unread postby Bobb » 14 Feb 2022, 11:36

Bon j'ai trouvé environ 200 fuites mémoire dans le programme à cause de la fonction subReplace et 2 ou 3 dans la fonction de tests des fonctions de chaînes de caracteres.
Je préviens que je n'ai pas mis à jour le code dans le premier message.

Tous mes programmes sont disponibles ici

↳ Testez mon simulateur Android sur Ti-83 Premium CE et / ou Édition Python
Jetez un coup d'oeil à mon langage de programmation interprété Neon.

Image
User avatar
BobbProgrammeur
Niveau 11: LV (Légende Vivante)
Niveau 11: LV (Légende Vivante)
Level up: 0.7%
 
Posts: 322
Joined: 19 Apr 2020, 12:37
Location: Morbihan
Gender: Male
Calculator(s):
MyCalcs profile
Class: ENS Rennes info


Return to Langages alternatifs

Who is online

Users browsing this forum: ClaudeBot [spider] and 6 guests

-
Search
-
Social TI-Planet
-
Featured topics
Comparaisons des meilleurs prix pour acheter sa calculatrice !
"1 calculatrice pour tous", le programme solidaire de Texas Instruments. Reçois gratuitement et sans aucune obligation d'achat, 5 calculatrices couleur programmables en Python à donner aux élèves les plus nécessiteux de ton lycée. Tu peux recevoir au choix 5 TI-82 Advanced Edition Python ou bien 5 TI-83 Premium CE Edition Python.
Enseignant(e), reçois gratuitement 1 exemplaire de test de la TI-82 Advanced Edition Python. À demander d'ici le 31 décembre 2024.
Aidez la communauté à documenter les révisions matérielles en listant vos calculatrices graphiques !
1234
-
Donations / Premium
For more contests, prizes, reviews, helping us pay the server and domains...
Donate
Discover the the advantages of a donor account !
JoinRejoignez the donors and/or premium!les donateurs et/ou premium !


Partner and ad
Notre partenaire Jarrety Calculatrices à acheter chez Calcuso
-
Stats.
1115 utilisateurs:
>1088 invités
>21 membres
>6 robots
Record simultané (sur 6 mois):
6892 utilisateurs (le 07/06/2017)
-
Other interesting websites
Texas Instruments Education
Global | France
 (English / Français)
Banque de programmes TI
ticalc.org
 (English)
La communauté TI-82
tout82.free.fr
 (Français)