Partage
  • Partager sur Facebook
  • Partager sur Twitter

Gérer les strings en C

    23 juin 2021 à 8:21:55

    Bonjour à tous et à toutes !

    J'écris ce post par pour des soucis mais juste pour partager la librairie que j'ai faite rapidement et simplement.

    Je voulais faire quelque chose de simple et utile pour se simplifier la vie avec les chaines de caractères.

    J'ai essayé de me baser sur la classe string du C++ pour faire les fonctions de base, j'en rajouterai plus par la suite.

    Pour l'utilisation de la lib tout est expliqué en anglais dans le readme mais je vais traduire ici.

    Il faut récupérer le dossier lib et le dossier include pour le mettre dans votre projet.

    Inclure le fichier stringC.h dans votre fichier .c.

    Pour la compilation : gcc src/*.c -o exemple -I ./include -L ./lib -lstringC

    - Il faut créer une variable de type string.

    string var;

    - Pour initialiser la variable :

    init(&var, "votre phrase à rentrer");

    -Pour connaître la longueur de la phrase:

    len(var);

    -Pour connaître la taille de la phrase (en bit) :

    size(var);

    -Pour ajouter du texte à la fin de votre phrase:

    appendEnd(&var, "la suite de la phrase");

    - Pour ajouter du texte au début de la phrase:

    appendStart(&var, "le debut de la phrase");

    -remplacer la phrase avec une nouvelle phrase:

    copy(&var, "le nouveau texte");

    -Pour renverser la phrase:

    reverse(&var);

    -Pour supprimer les n caractères à partir de la fin:

    popEnd(&var, n);

    -Pour supprimer les n caractères à partir du début:

    popStart(&var, n);

    -Pour enlever tous les caractères de la phrase mais garder la string en mémoire (après cette action, on peut copy ou append):

    clear(&var);

    -Pour enlever tous les caractères de la phrase et la détruire (après cette action, il faudra initialiser de nouveau):

    destroy(&var);

    -pour afficher le texte:

    println(var);

    Je sais que ce projet est petit (j'ai mis 30 minutes pour le faire) mais je le trouve très utile et donc je voulais vous le partager pour vous simplifier la vie aussi !:D

    Puis ça ma permis aussi de travailler avec les pointeurs, donc un bon exo à refaire je trouve !

    https://github.com/Manah3/stringC

    -
    Edité par Van3ll0pe 23 juin 2021 à 8:28:22

    • Partager sur Facebook
    • Partager sur Twitter
      23 juin 2021 à 9:10:31

      C'est effectivement un des premier trucs qu'on a tendance à faire. C'est un bon exercice mais après on a plutôt tendance à utiliser ce qui existe déjà ou ce qu'une bibliothèque propose. Par exemple si tu fais une application en Gtk, tu as plein de fonction dans la glib pour gérer les chaines.

      Concernant ton code :

      Tes fonctions devraient être préfixées par quelque chose. C'est joli un nom comme “clear” mais c'est beaucoup trop neutre et ça risque de rentrer en collision avec beaucoup d'autres nom. En C on a tendance à préfixer par nom de module. Exemple : string_new, string_append, string_clear, string_printf, etc.

      Pourquoi tu utilises la notation (*str).blabla ? Toute personne sensée utilise str->blabla.

      Tu ne teste pas le retour de malloc, bien que ce soit rare ça peut quand même échouer.

      • Ligne 7, un memcpy sera bien plus efficace, c'est une fonction largement optimisée par processeur.
      • Ligne 15, renvoie un size_t, pas un int. C'est un type pour stocker une taille. Si tu stockais la taille de ta chaîne dans ta structure ça t'éviterai de la recalculer tout le temps.
      • Tes fonctions appendEnd et appendStart sont beaucoup trop compliqué. Ça pourrait être largement simplifié à coup de memcpy.
      • Ligne 52, utilise des size_t pour les index en entrée. Ne fais pas non plus de programmation défensive car ce n'est pas à ta fonction de s'assurer que le paramètre est dans les bornes mais au développeur. Un assert est plus judicieux pour ça.
      • Ligne 61, même remarque, et aussi optimisable à coup de memmove.
      • Ligne 81, je commence à me répéter, memcpy ! :)

      Pas mal de choses à améliorer !

      -
      Edité par markand 23 juin 2021 à 9:11:47

      • Partager sur Facebook
      • Partager sur Twitter

      git is great because Linus did it, mercurial is better because he didn't.

        23 juin 2021 à 9:52:48

        markand a écrit:

        C'est effectivement un des premier trucs qu'on a tendance à faire. C'est un bon exercice mais après on a plutôt tendance à utiliser ce qui existe déjà ou ce qu'une bibliothèque propose. Par exemple si tu fais une application en Gtk, tu as plein de fonction dans la glib pour gérer les chaines.

        Concernant ton code :

        Tes fonctions devraient être préfixées par quelque chose. C'est joli un nom comme “clear” mais c'est beaucoup trop neutre et ça risque de rentrer en collision avec beaucoup d'autres nom. En C on a tendance à préfixer par nom de module. Exemple : string_new, string_append, string_clear, string_printf, etc.

        Pourquoi tu utilises la notation (*str).blabla ? Toute personne sensée utilise str->blabla.

        Tu ne teste pas le retour de malloc, bien que ce soit rare ça peut quand même échouer.

        • Ligne 7, un memcpy sera bien plus efficace, c'est une fonction largement optimisée par processeur.
        • Ligne 15, renvoie un size_t, pas un int. C'est un type pour stocker une taille. Si tu stockais la taille de ta chaîne dans ta structure ça t'éviterai de la recalculer tout le temps.
        • Tes fonctions appendEnd et appendStart sont beaucoup trop compliqué. Ça pourrait être largement simplifié à coup de memcpy.
        • Ligne 52, utilise des size_t pour les index en entrée. Ne fais pas non plus de programmation défensive car ce n'est pas à ta fonction de s'assurer que le paramètre est dans les bornes mais au développeur. Un assert est plus judicieux pour ça.
        • Ligne 61, même remarque, et aussi optimisable à coup de memmove.
        • Ligne 81, je commence à me répéter, memcpy ! :)

        Pas mal de choses à améliorer !

        -
        Edité par markand il y a 27 minutes

        Je suis une personne insensée :lol: ! (je connaissais les deux mais bon)

        En tout cas merci pour ton retour, je ferai des améliorations dessus, que ce soit les noms comme l'utilisation de memcpy pour gagner en performance.

        Même si c'est un petit projet "assez bâteau" j'espère que ça peut aider.

        En tout cas là je bosse sur de plus gros projets perso (dans mon temps libre) avec de grosse notions pour en apprendre toujours plus, comme le ray-casting et ray-stracing. C'est vraiment super intéressant !:)

        edit : j'ai vu tes BEAUX  et IMPRESSIONNANTS projets. libbuf est similaire à stringC non ?

        -
        Edité par Van3ll0pe 23 juin 2021 à 10:07:15

        • Partager sur Facebook
        • Partager sur Twitter
          23 juin 2021 à 10:55:39

          Manah3 a écrit:

          edit : j'ai vu tes BEAUX  et IMPRESSIONNANTS projets. libbuf est similaire à stringC non ?


          Merci :)

          C'est similaire, très minimaliste mais je m'en sers que sur des systèmes n'étant pas conforme POSIX. Car sous POSIX on a les deux fonctions fmemopen et open_memstream qui te permettent d'écrire / lire dans un buffer grâce à un FILE (et donc les fonctions fprintf, fputc, fputs, fgets, fscanf, etc) du coup plutôt convivial. Les deux fonctions seront peut-être dans la prochaine norme du C. fmemopen est utilisable en lecture et écriture mais sur des buffers à taille fixe. open_memstream est utilisée pour écrire uniquement, dans un buffer qui se réalloue quand c'est nécessaire.

          -
          Edité par markand 23 juin 2021 à 11:46:17

          • Partager sur Facebook
          • Partager sur Twitter

          git is great because Linus did it, mercurial is better because he didn't.

            24 août 2021 à 0:12:10

            markand a écrit:

            C'est effectivement un des premier trucs qu'on a tendance à faire. C'est un bon exercice mais après on a plutôt tendance à utiliser ce qui existe déjà ou ce qu'une bibliothèque propose. Par exemple si tu fais une application en Gtk, tu as plein de fonction dans la glib pour gérer les chaines.

            Concernant ton code :

            Tes fonctions devraient être préfixées par quelque chose. C'est joli un nom comme “clear” mais c'est beaucoup trop neutre et ça risque de rentrer en collision avec beaucoup d'autres nom. En C on a tendance à préfixer par nom de module. Exemple : string_new, string_append, string_clear, string_printf, etc.

            Pourquoi tu utilises la notation (*str).blabla ? Toute personne sensée utilise str->blabla.

            Tu ne teste pas le retour de malloc, bien que ce soit rare ça peut quand même échouer.

            • Ligne 7, un memcpy sera bien plus efficace, c'est une fonction largement optimisée par processeur.
            • Ligne 15, renvoie un size_t, pas un int. C'est un type pour stocker une taille. Si tu stockais la taille de ta chaîne dans ta structure ça t'éviterai de la recalculer tout le temps.
            • Tes fonctions appendEnd et appendStart sont beaucoup trop compliqué. Ça pourrait être largement simplifié à coup de memcpy.
            • Ligne 52, utilise des size_t pour les index en entrée. Ne fais pas non plus de programmation défensive car ce n'est pas à ta fonction de s'assurer que le paramètre est dans les bornes mais au développeur. Un assert est plus judicieux pour ça.
            • Ligne 61, même remarque, et aussi optimisable à coup de memmove.
            • Ligne 81, je commence à me répéter, memcpy ! :)

            Pas mal de choses à améliorer !

            -
            Edité par markand 23 juin 2021 à 9:11:47


            Désolé pour l'update :lol:.

            Je reviens en force en proposant quelque chose d'un peu amélioré.

            Tout d'abord j'ai changé les noms des fonctions afin d'éviter un problème. de plus j'ai rajouté les variables dans une structure utilisé dans ma structure principale car j'ai ajouté des pointeurs de fonction dans ma structure principale qui vont faire appel aux fonctions qui prendront un pointeur sur la structure qui stocke les variables.

            du coup pour lancer la fonction on utilise le pointeur de fonction et du coup ma structure se comporte un peu comme une classe même si elle n'y ressemble pas.

            Tout fonctionne, le projet est dispo sur le github : https://github.com/Manah3/stringC

            j'ai pu apprendre cette notion de pointeur de fonction donc j'ai pu encore apprendre un truc super intéressant !

            -
            Edité par Van3ll0pe 24 août 2021 à 0:12:48

            • Partager sur Facebook
            • Partager sur Twitter

            Gérer les strings en C

            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
            • Editeur
            • Markdown