IMPLÉMENTATION DE LA GESTION STANDARD DES CHAINES DE CARACTÈRES
excrt
Messages postés75Date d'inscriptionmercredi 5 avril 2006StatutMembreDernière intervention 3 juillet 2006
-
13 avril 2006 à 20:38
Cphil51
Messages postés87Date d'inscriptionjeudi 22 juin 2006StatutMembreDernière intervention24 septembre 2007
-
3 mars 2007 à 11:40
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.
Cphil51
Messages postés87Date d'inscriptionjeudi 22 juin 2006StatutMembreDernière intervention24 septembre 2007 3 mars 2007 à 11:40
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")
cs_satellite34
Messages postés688Date d'inscriptionmercredi 6 avril 2005StatutMembreDernière intervention 2 juin 20061 23 avril 2006 à 19:54
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.
excrt
Messages postés75Date d'inscriptionmercredi 5 avril 2006StatutMembreDernière intervention 3 juillet 2006 23 avril 2006 à 18: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
cs_satellite34
Messages postés688Date d'inscriptionmercredi 6 avril 2005StatutMembreDernière intervention 2 juin 20061 21 avril 2006 à 15:33
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
cs_satellite34
Messages postés688Date d'inscriptionmercredi 6 avril 2005StatutMembreDernière intervention 2 juin 20061 21 avril 2006 à 15:27
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;
BunoCS
Messages postés15475Date d'inscriptionlundi 11 juillet 2005StatutModérateurDernière intervention23 avril 2024103 14 avril 2006 à 09:39
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
excrt
Messages postés75Date d'inscriptionmercredi 5 avril 2006StatutMembreDernière intervention 3 juillet 2006 14 avril 2006 à 05:05
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... :) »
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 ...
*/
/*
* dans ton code, tu tente de mettre ton
* « StrGetLength() » compatible « utf8 »
* mais, que fais-tu du reste de ton code?
* tes « StrToLower() » et compagnie ???
*/
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;
}
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;
}
BunoCS
Messages postés15475Date d'inscriptionlundi 11 juillet 2005StatutModérateurDernière intervention23 avril 2024103 13 avril 2006 à 22:41
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...
Merci pour vos remarques. Je fais les changements nécessaires...
vecchio56
Messages postés6535Date d'inscriptionlundi 16 décembre 2002StatutMembreDernière intervention22 août 201014 13 avril 2006 à 21:57
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
excrt
Messages postés75Date d'inscriptionmercredi 5 avril 2006StatutMembreDernière intervention 3 juillet 2006 13 avril 2006 à 20:38
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?
3 mars 2007 à 11:40
23 avril 2006 à 19:54
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.
23 avril 2006 à 18:17
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
21 avril 2006 à 15:33
21 avril 2006 à 15:27
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;
14 avril 2006 à 09:39
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
14 avril 2006 à 05:05
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 =-=-
13 avril 2006 à 22:41
- 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...
13 avril 2006 à 21:57
J'ai pas trop compris non plus pourquoi tu gères les listes d'arguments variables comme ca, c'est dommage
13 avril 2006 à 20:38
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?