Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

IMPLÉMENTATION DE LA GESTION STANDARD DES CHAINES DE CARACTÈRES


Information sur la source

Catégorie :Chaîne de caractères Classé sous : sprintf, string, conversion, itoa Niveau : Initié Date de création : 12/04/2006 Date de mise à jour : 14/04/2006 12:06:54 Vu / téléchargé: 6 527 / 451

Note :
6,67 / 10 - par 3 personnes
6,67 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (10)
Ajouter un commentaire et/ou une note


Description

Cliquez pour voir la capture en taille normale
Cette source contient une implémentation de la gestion standard des chaines de caractères en C.
Par standard, j'entends les fonctionnalités que l'on peut trouver dans string.h (strlen, strcmp, strstr,...).
Je rajoute de plus une implémentation de la fonction sprintf().
Et pour ceux qui cherchent comment convertir un int en char *,je fournis les fonctions suivantes: itoa, itox, itoX, ltoa, ftoa, itob, itoo
 

Conclusion

Pour plus de détail, voir le fichier StrLib.h.
A venir:
- mettre tout ça dans une dll, pourquoi pas?
- Gestion des encodages UTF-8 et UCS-2
 

Fichier Zip

Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip

Historique

14 avril 2006 12:06:54 :
Prise en compte des remarques de Excrt (meilleure gestion de la liste des arguments variables, suppression des malloc dans StrCompareNoCase())

Commentaires et avis

signaler à un administrateur
Commentaire de excrt le 13/04/2006 20:38:00

pour les listes d'arguments variables, utilise <stdarg.h>, ton code n'est pas du tout portable, tu es limité a une plate-forme compatible intel et 32bits uniquement ...
pour la « transformation » des chaines(ToLower/ToUpper/...), n'utilises pas malloc() stp, c'est vraiment lourd tout ca ... 1/10, désolé.

En passant, ta librairie est en C mais tes testes en C++(main.cpp), why?

signaler à un administrateur
Commentaire de vecchio56 le 13/04/2006 21:57:09 administrateur CS

Je remarque tes commentaires style JavaDoc. Tu peux générer de la doc avec ca? (Comment fais tu?)
J'ai pas trop compris non plus pourquoi tu gères les listes d'arguments variables comme ca, c'est dommage

signaler à un administrateur
Commentaire de buno le 13/04/2006 22:41:19

Excrt >
- Malloc trop lourd? Ben voyons... De plus, malloc n'apparaît que dans une seule méthode: CompareNoCase. Tu ferais comment? Un parcours des 2 chaines, une conversion à la volée et une comparaison?
- main.cpp ne contient que du C. Quand tu crée un nouveau fichier sous Visual, il te met par défaut l'extension C++. Mais bon, rien de grave. Si cela te gêne, je vais le changer
- Pour la liste des arguments, il y a 2 méthodes pour le faire: la mienne et la votre. J'avais donc une chance sur 2 de me planter... :)
=> Un petit 1/10? Tu décrédibilise ma source par rapport aux débutants rien que pour des remarques mineures?? Sniff... Moi qui pensait en aider plus d'un...

Vecchio > Effectivement, je peux générer de la doc en utilisant Doxygen. Pour plus de détails, je te renvoie à mon tutoriel sur le sujet: http://www.cppfrance.com/codes/PRESENTATION-DOXYGEN_34770.aspx

Merci pour vos remarques. Je fais les changements nécessaires...

signaler à un administrateur
Commentaire de excrt le 14/04/2006 05:05:18

Pour le fichier main.cpp, look les options, j'ai aussi MSVC et il ne me cré pas de fichier avec l'extension « .cpp » par défaut.

ton main() est « Totalement » faux:

int main(char ** argc, int argv)  <<<<< MÔVÈS !!!
int main(int argc, char** argv) <<<<<< GOOD !!!
int main(int argc, char* argv[]) <<<<<< GOOD !!!

« - Pour la liste des arguments, il y a 2 méthodes pour le faire: la mienne et la votre. J'avais donc une chance sur 2 de me planter... :) »

non, il n'y a qu'une « bonne » méthode ...

#include <stdarg.h>
va_list, va_start(), va_arg(), va_end()

ta méthode, comme j'ai expliqué plus haut, est limitée aux plate-formes compatibles intel et 32bits ... c'est pas fonctionnel « du-tout » sous 64bits et autres plate-formes ...

« main.cpp ne contient que du C. »

faux, en C la déclaration des variables se fait en « DÉBUT » de scope, toi tu en déclare un peu partout dans ton main() ... ce n'est pas du C mais du C++


/*
* dans le même esprit que ta « librairie »
* en vérifiant les pointeurs « NULL » et compagnie ...
*
* le tout a été codé directement ici, donc désolé
* pour les fautes de frappes s'il y en a ...
*/

#include <stddef.h> /* size_t */
#include <ctype.h> /* tolower() */

/*
* dans ton code, tu tente de mettre ton
* « StrGetLength() » compatible « utf8 »
* mais, que fais-tu du reste de ton code?
* tes « StrToLower() » et compagnie ???
*/

/*
* StringLength()
*/
size_t __cdecl StringLength(const char* string)
{
  const char* start = string;

  if (string != NULL)
  {
    for (; *string != '\0'; string++)
      /*nothing*/;
  }
  return (size_t)(string - start);
}

/*
* StringCopy()
*/
char* __cdecl StringCopy(char* target, const char* source)
{
  char* start = target;

  if (target != NULL)
  {
    if (source != NULL)
    {
      while (*source != '\0') {
        *target++ = *source++;
      }
    }
    *target = '\0'; /* ajout d'un '\0' même si « source » vaut NULL, ca nous donnes une chaine valide */
  }
  return start;
}

/*
* StringCopyN()
*/
char* __cdecl StringCopyN(char* target, const char* source, size_t count)
{
  char* start = target;

  if (target != NULL)
  {
    if (source != NULL)
    {
      while (count-- != 0 && *source != '\0') {
        *target++ = *source++;
      }
    }
    *target = '\0';
  }
  return start;
}

/*
* StringAppend()
*/
char* __cdecl StringAppend(char* target, const char* source)
{
  char* start = target;

  if (target != NULL && source != NULL)
  {
    for (; *target != '\0'; target++)
      /*nothing*/;

    while ((*target++ = *source++) != '\0')
      /*nothing*/;
  }
  return start;
}

/*
* StringAppendN()
*/
char* __cdecl StringAppendN(char* target, const char* source, size_t count)
{
  char* start = target;

  if (target != NULL && source != NULL && count != 0)
  {
    for (; *target != '\0'; target++)
      /*nothing*/;
    do
    {
      if ((*target++ = *source++) == '\0') {
        return start;
      }
    }
    while (--count != 0);

    *target = '\0';
  }
  return start;
}

/*
* StringCompare()
*/
int __cdecl StringCompare(const char* string1, const char* string2)
{
  if (string1 != NULL && string2 != NULL)
  {
    while (*string1 == *string2 && *string1 != '\0') {
      string1++, string2++;
    }
    return (int)(*(unsigned char*)string1 - *(unsigned char*)string2);
  }
  return (int)(string1 - string2);
}

int __cdecl StringCompareNoCase(const char* string1, const char* string2)
{
  char ch1;
  char ch2;

  if (string1 != NULL && string2 != NULL)
  {
    do
    {
      ch1 = (char)tolower(*(unsigned char*)string1);
      string1++;

      ch2 = (char)tolower(*(unsigned char*)string2);
      string2++;
    }
    while (ch1 == ch2 && ch1 != '\0');

    return (int)(ch1 - ch2);
  }
  return (int)(string1 - string2);
}

int __cdecl StringCompareN(const char* string1, const char* string2, size_t count)
{
  if (string1 != NULL && string2 != NULL)
  {
    if (count != 0)
    {
      while (--count != 0 && *string1 == *string2 && *string1 != '\0') {
        string1++, string2++;
      }
      return (int)(*(unsigned char*)string1 - *(unsigned char*)string2);
    }
    return 0;
  }
  return (int)(string1 - string2);
}

int __cdecl StringCompareNoCaseN(const char* string1, const char* string2, size_t count)
{
  char ch1;
  char ch2;

  if (string1 != NULL && string2 != NULL)
  {
    if (count != 0)
    {
      do
      {
        ch1 = (char)tolower(*(unsigned char*)string1);
        string1++;

        ch2 = (char)tolower(*(unsigned char*)string2);
        string2++;
      }
      while (--count != 0 && ch1 == ch2 && ch1 != '\0');

      return (int)(ch1 - ch2);
    }
    return 0;
  }
  return (int)(string1 - string2);
}

/*
* StringFindFirstChar()
*/
char* __cdecl StringFindFirstChar(const char* string, char character)
{
  if (string != NULL)
  {
    while (*string != character && *string != '\0') {
      string++;
    }
    if (*string == character) {
      return (char*)string;
    }
  }
  return NULL;
}

char* __cdecl StringFindFirstCharNoCase(const char* string, char character)
{
  if (string != NULL)
  {
    character = (char)tolower((unsigned char)character);
    do
    {
      if ((char)tolower(*(unsigned char*)string) == character) {
        return (char*)string;
      }
    }
    while (*string++ != '\0');
  }
  return NULL;
}

char* __cdecl StringFindLastChar(const char* string, char character)
{
  const char* last = NULL;

  if (string != NULL)
  {
    do
    {
      if (*string == character) {
        last = string;
      }
    }
    while (*string++ != '\0');
  }
  return (char*)last;
}

char* __cdecl StringFindLastCharNoCase(const char* string, char character)
{
  const char* last = NULL;

  if (string != NULL)
  {
    character = (char)tolower((unsigned char)character);
    do
    {
      if ((char)tolower(*(unsigned char*)string) == character) {
        last = string;
      }
    }
    while (*string++ != '\0');
  }
  return (char*)last;
}

/*
* StringFindFirst()
*/
char* __cdecl StringFindFirst(const char* string, const char* substr)
{
  const char* str;
  const char* sub;

  if (string != NULL && substr != NULL)
  {
    for (; *string != '\0'; string++)
    {
      str = string;
      sub = substr;

      while (*str == *sub && *sub != '\0') {
        str++, sub++;
      }
      if (*sub == '\0') {
        return (char*)string;
      }
    }
  }
  return NULL;
}

char* __cdecl StringFindFirstNoCase(const char* string, const char* substr)
{
  char ch1;
  char ch2;
  const char* str;
  const char* sub;

  if (string != NULL && substr != NULL)
  {
    for (; *string != '\0'; string++)
    {
      str = string;
      sub = substr;

      do
      {
        ch1 = (char)tolower(*(unsigned char*)str);
        str++;

        ch2 = (char)tolower(*(unsigned char*)sub);
        sub++;
      }
      while (ch1 == ch2 && ch2 != '\0');

      if (ch2 == '\0') {
        return (char*)string;
      }
    }
  }
  return NULL;
}

char* __cdecl StringFindLast(const char* string, const char* substr)
{
  const char* str;
  const char* sub;
  const char* last = NULL;

  if (string != NULL && substr != NULL)
  {
    for (; *string != '\0'; string++)
    {
      str = string;
      sub = substr;

      while (*str == *sub && *sub != '\0') {
        str++, sub++;
      }
      if (*sub == '\0') {
        last = string;
      }
    }
  }
  return (char*)last;
}

char* __cdecl StringFindLastNoCase(const char* string, const char* substr)
{
  char ch1;
  char ch2;
  const char* str;
  const char* sub;
  const char* last = NULL;

  if (string != NULL && substr != NULL)
  {
    for (; *string != '\0'; string++)
    {
      str = string;
      sub = substr;

      do
      {
        ch1 = (char)tolower(*(unsigned char*)str);
        str++;

        ch2 = (char)tolower(*(unsigned char*)sub);
        sub++;
      }
      while (ch1 == ch2 && ch2 != '\0');

      if (ch2 == '\0') {
        last = string;
      }
    }
  }
  return (char*)last;
}

/*
* String<Lower|Upper>()
*/
char* __cdecl StringLower(char* string)
{
  char* start = string;

  if (string != NULL)
  {
    for (; *string != '\0'; string++) {
      *string = (char)tolower(*(unsigned char*)string);
    }
  }
  return start;
}

char* __cdecl StringLowerN(char* string, size_t count)
{
  char* start = string;

  if (string != NULL)
  {
    for (; count-- != 0 && *string != '\0'; string++) {
      *string = (char)tolower(*(unsigned char*)string);
    }
  }
  return start;
}

char* __cdecl StringUpper(char* string)
{
  char* start = string;

  if (string != NULL)
  {
    for (; *string != '\0'; string++) {
      *string = (char)toupper(*(unsigned char*)string);
    }
  }
  return start;
}

char* __cdecl StringUpperN(char* string, size_t count)
{
  char* start = string;

  if (string != NULL)
  {
    for (; count-- != 0 && *string != '\0'; string++) {
      *string = (char)toupper(*(unsigned char*)string);
    }
  }
  return start;
}

/*
* StringReverse()
*/
char* __cdecl StringReverse(char* string)
{
  char temp;
  char* left;
  char* right;

  if (string != NULL)
  {
    for (right = string; *right != '\0'; right++)
      /*nothing*/;

    for (left = string; left < --right; )
    {
      temp = *left;
      *left++ = *right;
      *right = temp;
    }
  }
  return string;
}

char* __cdecl StringReverseN(char* string, size_t count)
{
  char temp;
  char* left;
  char* right;

  if (string != NULL)
  {
    for (right = string; count-- != 0 && *right != '\0'; right++)
      /*nothing*/;

    for (left = string; left < --right; )
    {
      temp = *left;
      *left++ = *right;
      *right = temp;
    }
  }
  return string;
}

/*
* etc... etc... etc...
*/



-=-= ExCRT =-=-

signaler à un administrateur
Commentaire de buno le 14/04/2006 09:39:06

Je n'ai absolument pas la prétention d'être le 1er à fournir une implémentation de ces API, je veux juste aider ceux qui sont dans le besoin (pour info, hier, il y a encore eu une question dans le forum: Conversion d'une chaine type "01001000" en binaire)...

J'ai laissé un UTF-8 dans mes commentaires!? Bon OK, j'avoue: pour la suite, il y aura une gestion des encodages UTF-8 et UCS-2.

Au fait, bienvenue sur CS :P

signaler à un administrateur
Commentaire de satellite34 le 21/04/2006 15:27:07

bonjour,

moi j'ai trouvé ça trés bien fait, celui qui a mis 1 pourrai se manifester et argumenter, je penses qu'il s'agit ici d'un abus.

j'augmente donc ta moyenne bien que ce soit un peu inutile mais quand meme, ca fait pas plaisir d'avoir 1/20 pour un travail effectué.

bravo;

signaler à un administrateur
Commentaire de satellite34 le 21/04/2006 15:33:08

lol, j'avais pas vu ke c'etait excrt, et ben, 1 pour ca, ben c'est assez zarb, 70% des codes de ce site valent 1 alors, selon excrt......a méditer

signaler à un administrateur
Commentaire de excrt le 23/04/2006 18:17:17

ouvres tes yeux satellite34, ce n'est pas 1/20 mais 1/10 :)
et oui, cette source vaut bien 1/10, pourquoi?

pas portable(plate-forme/types utilisés/...)
pas optimisé
pas toujours compréhensible
...
et oui, il faut le dire, inutile ...

pour les conversions, je peux comprendre, chaine<->binaire/binaire<->chaine/chaine<->double/...
mais pour ce qui est de « refaire » strlen()/strcpy()/strcat()/... je suis désolé mais c'est d'une « inutilitée totale ». pour ceux/celles qui veulent ajouter une chaine à la suite d'une autre, la réponse est très simple:

#include <string.h>
strcat(ajouter_ici, ceci);

si tu veux te lancer dans l'unicode alors vas-y, je t'encourage a le faire, mais pour ce genre de chose, je vais plutôt faire le contraire ...

note, pour les conversions:
<stdlib.h> ==>> strtol()/strtod()/...
<stdio.h>  ==>> snprintf()/...
<wchar.h>  ==>> wcstol()/wcstod()/snwprintf()/...

« Au fait, bienvenue sur CS :P », merci

signaler à un administrateur
Commentaire de satellite34 le 23/04/2006 19:54:27

peut etre mais cela représente un effort, un travail qui mérite d'etre mentionné, la note la plus basse sert donc a indisuer qu'il n'y a eu aucun effort personnel, genre copi-colle, ou bien un truk vraiment bateau, hors la , manifestement, il ya eu travail donc au pire des cas, 5/10, mais en aucun cas 1.

voila, sinon, ce genre de programmation ne m'interresse pas vraiment donc je vais pas zieuter a fond mais il ya eu un travail donc ça se respecte.

signaler à un administrateur
Commentaire de Cphil51 le 03/03/2007 11:40:59

Intéressant. J'ai rajouté un 9 pour remonter le 1 (note < 5 réservé aux code copiés et aux trucs qui sont "vides")

Ajouter un commentaire

Discussions en rapport avec ce code source dans le forum

conversion d'un string [ par bastiente ] Ba$t :bonjour... Voila je travaille sur un fichier ou figure la valeur : 32 989,88Je dois la retourner dan un autre fichier. Ca c'est fait, mai je doi Conversion "system::string __gc *" vers "char *"....HELP [ par starkrous ] oui ce cher "name" dans Fileinfo ne se presente pas sous une forme chaine de caractere...du coup ça m'empeche un peu de le manipuler, est ce qu'il y a Conversion Float to String [ par PierreP ] Bonjour à tous !je suis en train de me prendre la tête pour créer une fonction de conversion d'un réel en une chaine de caractère (problème du débutan conversion double en string [ par bouba ] Bonjour, je réalise une fonction qui doit calculer le nombre de caractères d'un doubleexemple:-7.56 -&gt; 5 caractèreExiste t'il une fonction qui fass conversion Byte en string [ par shaolinn ] &lt;&lt;&lt;SHaoLInn&gt;&gt;&gt;&gt;&gt;voila j'ai une fonction void fonction ( byte parametre )j'ai une CString ki contien "xxxxyxxxxxx"Comment incl Conversion string en date [ par jpeg ] j'aimerai convertir (en C++ standard, sans MFC) une chaine de caractère de n'importe quel format (DD/MM/YYYY ou DD/MM/YYYY hh:mm ou YYYYMMDD ou ....) Conversion des types string en int [ par tanguy_laverdure ] Bonjour, j'essai en vain de convertir un type string en int. Y a t il des méthodes directes de string.h qui permettent de faire cela ou faut il me fai Conversion de char[] ( C++ non managé ) vers un string ( C# ) [ par LUDINSKI ] Ben, voilà ! Je me bas depuis quelque heures avec cette conversion...Il faut que je convertisse un tableau de char provenant du C++ ( que je reçois vi Comment utiliser des methodes privées ? [ par thomas59553 ] bonjour, j'ai un probleme dans une classe de conversion ... en voici un extrait :class Conversion{ private : string Nombre; conversion string en int [ par Gipsy974 ] salut, je souhaite convertir un string en int, mais sachant que le stiring peut etre tres grand , parfois trop pour un int j&nbsp; aimerai savoir une


Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Téléchargements

Logiciels à télécharger sur le même thème :

Comparez les prix Nouvelle version

Photothèque Nouveau !



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
Temps d'éxécution de la page : 0,811 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.