begin process at 2012 05 27 19:26:40
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Chaîne de caractères

 > LES STRING EN C, AFFECTATION, CONCATÉNATION, SPLIT, ...

LES STRING EN C, AFFECTATION, CONCATÉNATION, SPLIT, ...


 Information sur la source

Note :
3,33 / 10 - par 3 personnes
3,33 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Chaîne de caractères Classé sous :string c, split c, concatenation, deconcatenation, chaine caractere Niveau :Débutant Date de création :01/03/2011 Vu / téléchargé :3 504 / 89

Auteur : appranting

Ecrire un message privé
Commentaire sur cette source (6)
Ajouter un commentaire et/ou une note

 Description

Le concept de string manque dans le langage C. Présent en C++ grâce à la POO, l'objet string facilite la vie des développeurs dès lors que l'on souhaite manipuler des chaine de caractère.
Si l'on se penche sur la question, il est assez aisé d'imiter le type string en langage C, en faisant de la "pseudo POO".
Sans la surcharge de méthodes et d'opérateurs, voici une petite source permettant de créer des Variables type string (les MSTRING), de leur affecter simplement une valeur, de les concaténer et de les spliter entre elles, etc...

les fonctions sont :
affect => affecter une chaine de caractère à une MSTRING
concat => concatène deux MSTRING
deconcat => split de MSTRING selon une MSTRING, c'est à dire que le délimiteur n'est pas un caractère mais bien une chaine de caractère.
equal => compare deux MSTRING
destroyM => détruit une MSTRING
destroyP => détruit un tableau de MSTRING (les PSTRING)

Les allocations sont dynamiques, et permettent en théorie de donner dynamiquement une taille à une MSTRING.
Les fonctions prennent un dernier paramètre de type MSTRING permettant de ne pas modifier les deux premier.

ex: concat(string1, string2, string3) renvoie string3 (string3 = string1+string2) ainsi string1 et string2 ne sont pas modifiés.

ATTENTION, nous ne sommes pas en C++, donc pas de destructeur, il est donc nécessaire de détruire manuellement chaque chaine(MSTRING) "construite" avec  destroyM() et chaque tableau de chaine(PMSTRING) avec destroyP().Eh oui! pas de miracle (vous croyiez quoi !!!).


J'ai testé le code sous valgrind (pour ceux qui connaissent), si les destruction de MSTRING se font correctement, il n'y a pas de fuite de mémoire.

Il doit certainement y avoir beaucoup d'améliorations à apporter, je peux juste dire qu'après avoir développé ces MSTRING, cela m'a beaucoup facilité la vie!!

Nul doute que les pros s'ennuieront devant cette source, puisqu'ils disposeront certainement des libs bien plus puissantes, mais j'ose espérer que certains débutants trouveront leur bonheur et que mes MSTRING dépanneront des codes sources =))

Développé sous CodeBlocks 8.02, Le code est portable et fonctionne donc sur tous les OS.


Source

  • #include "mstring.h"
  • MSTRING affect(const char *valeur ,MSTRING chaine)
  • {
  • int taille = 0;
  • int compteur = 0;
  • while( valeur[taille] != '\0')
  • {
  • taille++;
  • }
  • chaine.taille = taille;
  • chaine.text = malloc(taille*sizeof(char));
  • for (compteur = 0; compteur < taille; compteur++)
  • {
  • chaine.text[compteur] = valeur[compteur];
  • }
  • chaine.text[chaine.taille] = '\0';
  • return chaine;
  • }
  • void destroyM(MSTRING chaine)
  • {
  • if( chaine.text != NULL)
  • {
  • free(chaine.text);
  • }
  • chaine.taille = 0;
  • }
  • void destroyP(PMSTRING Pchaine)
  • {
  • int i = 0;
  • for (i = 0; i < Pchaine.nbresschaine; i++)
  • {
  • destroyM(Pchaine.chaine[i]);
  • }
  • if (Pchaine.chaine != NULL)
  • {
  • free(Pchaine.chaine);
  • }
  • Pchaine.nbresschaine = 0;
  • }
  • MSTRING concat(MSTRING debut, MSTRING fin,MSTRING sortie)
  • {
  • int compteur = 0;
  • sortie.taille = debut.taille + fin.taille;
  • sortie.text = malloc(sizeof(char) * sortie.taille);
  • for(compteur = 0; compteur < debut.taille ; compteur++)
  • {
  • sortie.text[compteur] = debut.text[compteur];
  • }
  • for(compteur = debut.taille; compteur < sortie.taille; compteur++)
  • {
  • sortie.text[compteur] = fin.text[compteur - debut.taille];
  • }
  • sortie.text[sortie.taille] = '\0';
  • return sortie;
  • }
  • PMSTRING deconcat(MSTRING entree, MSTRING delimiter, PMSTRING sortie)
  • {
  • char *pointer = NULL;
  • MSTRING temp;
  • int occurence = 0;
  • int index = 0;
  • if ( entree.text != NULL && delimiter.text != NULL )
  • {
  • temp = affect(entree.text,temp);
  • if(( pointer = strtok(temp.text,delimiter.text)) != NULL)
  • {
  • do
  • {
  • occurence++;
  • }while((pointer = strtok(NULL,delimiter.text)) != NULL);
  • sortie.nbresschaine = occurence;
  • sortie.chaine = malloc(sizeof(MSTRING)*occurence);
  • pointer = NULL;
  • destroyM(temp);
  • temp = affect(entree.text,temp);
  • if(( pointer = strtok(temp.text,delimiter.text)) != NULL)
  • {
  • do
  • {
  • sortie.chaine[index] = affect(pointer,sortie.chaine[index]);
  • index++;
  • }while ((pointer = strtok(NULL,delimiter.text)) != NULL);
  • }
  • }
  • }
  • destroyM(temp);
  • return sortie;
  • }
  • int equal(MSTRING string1, MSTRING string2)
  • {
  • int count = 0;
  • if ( string1.taille == string2.taille)
  • {
  • for ( count = 0; count < string1.taille; count++ )
  • {
  • if ( string1.text[count] != string2.text[count] )
  • {
  • return ERROR;
  • }
  • }
  • }
  • else
  • {
  • return ERROR;
  • }
  • return SUCCESS;
  • }
#include "mstring.h"


MSTRING affect(const char *valeur ,MSTRING chaine)
{
    int taille = 0;
    int compteur = 0;

    while( valeur[taille] != '\0')
    {
        taille++;
    }

    chaine.taille = taille;
    chaine.text = malloc(taille*sizeof(char));

    for (compteur = 0; compteur < taille; compteur++)
    {
        chaine.text[compteur] = valeur[compteur];
    }
    chaine.text[chaine.taille] = '\0';

    return chaine;
}

void destroyM(MSTRING chaine)
{
    if( chaine.text != NULL)
    {
        free(chaine.text);
    }
    chaine.taille = 0;
}

void destroyP(PMSTRING Pchaine)
{
    int i = 0;

    for (i = 0; i < Pchaine.nbresschaine; i++)
    {
      destroyM(Pchaine.chaine[i]);
    }

    if (Pchaine.chaine != NULL)
    {
      free(Pchaine.chaine);
    }
    Pchaine.nbresschaine = 0;
}


MSTRING concat(MSTRING debut, MSTRING fin,MSTRING sortie)
{
    int compteur = 0;

    sortie.taille = debut.taille + fin.taille;
    sortie.text = malloc(sizeof(char) * sortie.taille);

    for(compteur = 0; compteur < debut.taille ; compteur++)
    {
        sortie.text[compteur] = debut.text[compteur];
    }
    for(compteur = debut.taille; compteur < sortie.taille; compteur++)
    {
        sortie.text[compteur] = fin.text[compteur - debut.taille];
    }

    sortie.text[sortie.taille] = '\0';

    return sortie;

}


PMSTRING deconcat(MSTRING entree, MSTRING delimiter, PMSTRING sortie)
{
    char *pointer = NULL;
    MSTRING temp;

    int occurence = 0;
    int index = 0;

    if ( entree.text != NULL && delimiter.text != NULL )
    {
            temp = affect(entree.text,temp);

        if(( pointer = strtok(temp.text,delimiter.text)) != NULL)
        {
            do
            {
                occurence++;
            }while((pointer = strtok(NULL,delimiter.text)) != NULL);

            sortie.nbresschaine = occurence;
            sortie.chaine = malloc(sizeof(MSTRING)*occurence);

            pointer = NULL;
            destroyM(temp);

            temp = affect(entree.text,temp);

            if(( pointer = strtok(temp.text,delimiter.text)) != NULL)
            {
                do
                {
                    sortie.chaine[index] = affect(pointer,sortie.chaine[index]);
                    index++;

                }while ((pointer = strtok(NULL,delimiter.text)) != NULL);
            }

        }
    }

    destroyM(temp);

    return sortie;
}


int equal(MSTRING string1, MSTRING string2)
{
    int count = 0;

    if ( string1.taille == string2.taille)
    {
        for ( count = 0; count < string1.taille; count++ )
        {
            if ( string1.text[count] != string2.text[count] )
            {
                return ERROR;
            }
        }
    }
    else
    {
        return ERROR;
    }

    return SUCCESS;
}

 Conclusion

Le C ça déchire quand même vachement finalement ...

 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !
  •   MSTRING
    • bin
    • obj
    • ChorseForSale.cbpTélécharger ce fichier [Réservé aux membres club]1 284 octets
    • ChorseForSale.layoutTélécharger ce fichier [Réservé aux membres club]539 octets
    • main.cTélécharger ce fichier [Réservé aux membres club]Voir ce fichier827 octets
    • MString.cTélécharger ce fichier [Réservé aux membres club]Voir ce fichier2 938 octets
    • MString.hTélécharger ce fichier [Réservé aux membres club]Voir ce fichier1 319 octets

Télécharger le zip


 Sources de la même categorie

CALCUL DE CLEF RIB par Renfield
Source avec Zip [C] WD_STRING V2.2 par cyberripper
Source avec Zip [C] WD_STRING V1.9 par cyberripper
Source avec Zip LIBRAIRIE LANGUAGES par astro53
FONCTION : CHAR * AJUSTERTAILLECHAINE() par Rockanos

 Sources en rapport avec celle ci

Source avec Zip Source avec une capture LISTE CHAINÉE par bazdig25
Source avec Zip GESTION FICHIERS TXT (INSERTION, CONCATÉNATION, DÉNOMBREMENT... par KissyFroth

Commentaires et avis

Commentaire de NoMitsu le 03/03/2011 21:51:45 1/10

se genre de gestion des strings est a proscrire et est peu performante. il faut mieux utiliser les fonctions de la libc dédier a la manipulation des string (strlen, strcpy ...).
En effet, pour passer les arguments MSTRING et PSTRING tu n'utilise pas de pointeur donc tu fait pour chaque appel une copie de la structure sur la stack. en plus tu n'utilise pas les fonctions de la libc qui sont bien plus performante que ton code et ensuite il faut absolument checker les valeurs de retour des syscall ! donc au lieu d'écrire par exemple ton affect comme tu l'as fait tu aurais du faire:

MSTRING* affect(const char *valeur ,MSTRING* chaine)
{
    chaine->taille = strlen(valeur);
    if ((chaine->text = malloc((chain->taille + 1) * sizeof(char))) == NULL)
      return (NULL);
    retun (strcmp(chaine->text, valeur));
}

se qui rend l'utilisation d'affect peu intéressante paraport a l'utilisation direct de la libc.

Commentaire de piergel le 07/03/2011 11:34:18 8/10

Même si je ne suis pas rentré dans le détail du code, moi je trouve que l'exercice est plutôt intéressant.

Pas d'accord avec NoMitsu sur la performance : tous les langages modernes qui permettent une gestion simple des chaines font de l'allocation dynamique donc à mon avis, les fonctions d'appranting sont compétitives en performance d'autant qu'elles restent simples.

Aucun problème non plus sur le passage des paramètres : certes ce ne sont pas des pointeurs mais des structures qui comportent un pointeur et un entier. Ce n'est pas très éloigné ! en tout cas, la chaîne en elle même (le tableau de char) n'est jamais passée en paramètre.

Là ou je suis d'accord avec NoMitsu par contre c'est sur le contrôle des malloc afin de s'assurer que l'allocation c'est bien passée.

Commentaire de chseyler le 07/03/2011 17:44:33 1/10

C'est une blague ?

Rien que dans la fonction affect(), il y a buffer overflow ... J'ai pas été plus loin pour voir si le reste est de la même "qualité" ...
Un peu de rigueur SVP !

Commentaire de NoMitsu le 09/03/2011 00:03:47

je n'ai rien contre l'allocation dynamique. c'est le reste de l'implem qui me dérange.
tien juste par curiosité j'ai fait un petit bench de 4 bouts de code.
Tous on pour objectif de copier une chaine de 10mo et de libérer la mémoire après copy.

implem "homemade" utilise le code donne par appranting:
void execute(void)
  {
    MSTRING tmp;

    affect(_string, tmp);
    destroyM(tmp);
  }
moyen pour 100 test 66279ms.

implem "cstring" identique a homemade mais avec les functions string de la libc:
void execute(void)
  {
    size_t size = strlen(_string);
    char* data = static_cast<char*>(malloc((size + 1) * sizeof(*_string)));
    if (data == NULL)
      throw "bad alloc";
    strcpy(data, _string);
    free(data);
  }
moyen pour 100 test 11304ms.

implem "strdup" simplification du "cstring" avec strdup:
void execute(void)
  {
    char* data = strdup(_string);
    if (data == NULL)
      throw "bad alloc";
    free(data);
  }
moyen pour 100 test 9013ms.

implem "stl" utilise la class string de la stl:
void execute(void)
  {
    std::string data(_string);
  }
moyen pour 100 test 9228ms.

récapitulatif

strdup 9013ms référence
homemade 66279ms 635%
stl 9228ms 2%
cstring 11304ms 25%

Commentaire de piergel le 09/03/2011 09:34:10

OK NoMitsu, belle démonstration ! je pensais pas qu'il pouvait y avoir une telle différence. Et voila qui va permettre à Appranting de rendre ses fonctions plus performantes et plus robustes !

Commentaire de katycumon le 01/05/2011 00:26:47

salut tout le monde.
J'ai un petit projet en C qui permet la saisi d'une fonction qlcq
et le calcul de son aire par 3 méthodes différentes.Maintenant j'ai établi le programme qui fait le calcul de l'aire de n'importe quelle fonction. Mais je me suis bloquée au niveau de la saisi de la fonction par clavier?
SVP j'ai besoin d'un programme en C qui permet la saisi d'une telle fonction??
merci de me répondre!
je suis à l'attente de vos réponses!

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

PROBLEME DE CONCATENATION [ par 24Karas ] PROBLEME DE CONCATENATION------------------------probleme :Je veux concaténer 2 chaines mais ça foireà l'exécution. Si vous savez pourquoi dîtes le mo Concatenation d'un CString et un int [ par FloZix ] Bonjour,J'ai un probleme de débutant... Je voudrai concatener une variable de type CString avec une variable de type int.Exemple:m_bilan="Vidange dans Concatenation [ par UnExPeCtEdSpy ] B'jour vousBon c'est tout bête je voudrais concaténer deux chaine de caractére, alors j'essaye avec :char *strcat( char *strDestination, const char *s concatenation [ par youpiyoyo ] il y a t'il un moyen de concatener deux char*vous allez me dire strcatmais ca fais planté mon prog Encore un Pb de concatenation [ par psycomel ] Bonsoir a tous!! je sais kil y a pleins de questions qui parlent des concaténation mais malheureusement on dirait kil n'y a pas mon cas...Ce que jessa concatenation [ par fcolh ] FcolHbonjour, je vooudrais savoir si il est possible de concatener deux strings et un saut de ligne ou un retour chariot et quelle est la syntaxeex: s concatenation [ par CCJ ] bonjour je cherche a concatener des cractere alphabetiques et alpha numérique dans un meme chaine mais je ny arrive pas : char password[7]; if (chiffr concatenation d'une chaîne de caractères [ par davdav73 ] Alors je c=programme sous builder 6 C++ et je voudrais savoir comment ajouter des chiffres entiers les uns apr&#232;s les autres. J'ai un pav&#233; nu concatenation LPCSTR [ par bandifull ] Bonjour,Je souhaiterai utiliser une fonction activeX qui prend en parametre un LPCSTR.Ce LPCSTR contient deux parties, une chaine de caractere (statiq concatenation de BYTE [ par elpens ] Bonjour,Je suis à la recherche d'une solution pour concaténer un tableau de BYTE, en 1 seul BytemonTableau[0] = 0xCAmonTableau[1] = 0x02monTableau[2]


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,530 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales