Author Topic: question de langage c.  (Read 6779 times)

0 Members and 1 Guest are viewing this topic.

Offline maracuja

  • Base
    • View Profile
question de langage c.
« on: 11 July 2011 à 18:26:39 »
Salut, je souhaite faire un sprintf en utilisant une chaine de format de ce type " blabla %d lala %l "  . Le truc qui me gène c’est de faire un buffer fixe  en utilisant un bon vieux tableaux de char. Y a t’il des solutions plus élégantes ?
« Last Edit: 11 July 2011 à 18:38:38 by maracuja »

Offline Patapom

  • Base
    • View Profile
    • www.patapom.com
  • Ancienneté: 1988
  • Groupe: Bomb!
  • Rôle: Coder
  • Ville: Lyon
Re : question de langage c.
« Reply #1 on: 11 July 2011 à 19:50:30 »
Vu que tu connais pas a priori la taille de la chaîne finale, je dirais : non.
Et voilà, un problème de + réglé ! ;D
.  Pom  .

Offline ponce

Re : question de langage c.
« Reply #2 on: 11 July 2011 à 20:11:09 »
Tu peux faire un wrapper de vsnprintf vers une std::string pour avoir un truc similaire au sprintf de PHP.

Offline maracuja

  • Base
    • View Profile
Re : question de langage c.
« Reply #3 on: 11 July 2011 à 21:40:18 »
Okay merci à tous deux. :)

Offline TarMil

  • Base
    • Pouet.net
    • View Profile
    • Greek Sugar Cake
  • Ancienneté: 2006
  • Groupe: Ctrl-Alt-Test
  • Rôle: Code
  • Ville: Villejuif
Re : question de langage c.
« Reply #4 on: 11 July 2011 à 22:23:18 »
Si tu codes sous linux (ou toute autre plateforme tournant avec la libc gnu), tu peux utiliser asprintf qui alloue le buffer.
- De l'eau ?
- J'ai la gorge sèche, pas les pieds sales.

Offline maracuja

  • Base
    • View Profile
Re : question de langage c.
« Reply #5 on: 12 July 2011 à 09:12:48 »
sympa comme info !
J’ai cru voir également que snprintf peut simuler la création de chaîne et retourner sa taille si le paramètre du buffer est NULL, cependant il faut être en « standard c99 » et je n’ai pas pu déterminer si visual supporte ce " paramètrage ".

Offline flure

  • Base
    • Pouet.net
    • View Profile
  • Ancienneté: 1998
  • Groupe: PoPsY TeAm
  • Rôle: Codeur Linux
  • Ville: Lyon
Re : question de langage c.
« Reply #6 on: 12 July 2011 à 17:57:28 »
Les chaînes en C, c'est toujours la merde...
C'est vraiment dommage qu'avec le temps et les nouvelles versions de la libc ils n'aient pas pensé à créer un type String à la Pascal/Delphi... Ou alors tu peux te le créer toi-même, mais c'est beaucoup de boulot. Remarque si tu le fais, partage :D

Offline maracuja

  • Base
    • View Profile
Re : question de langage c.
« Reply #7 on: 12 July 2011 à 19:09:41 »
En gros, il faudrait refaire les AnsiString de pascal et bcb. :)

Leur technique est quasi identique a ce qui est fait sur nginx. Il utilise une structure de un word ou dword pour stocker la taille de la chaine et ensuite il s’agit d’une chaine codée en wchar_t. Et il y a un ensemble de fonction qui travaille dessus. Le truc brillant, c’était  le strlen de pascal ; en un coup il récupère la taille de la chaine.
« Last Edit: 12 July 2011 à 19:13:19 by maracuja »

Offline flure

  • Base
    • Pouet.net
    • View Profile
  • Ancienneté: 1998
  • Groupe: PoPsY TeAm
  • Rôle: Codeur Linux
  • Ville: Lyon
Re : question de langage c.
« Reply #8 on: 12 July 2011 à 19:30:08 »
Tout à fait.
Je pense si quelqu'un s'y colle à faire cette lib, ça va plaire à beaucoup de monde :D

Offline LLB

  • Base
    • Pouet.net
    • Coup de coeur
    • View Profile
    • site perso
  • Ancienneté: 2000
  • Groupe: Ctrl-Alt-Test
  • Rôle: code
  • Ville: Munich
Re : question de langage c.
« Reply #9 on: 13 July 2011 à 12:00:15 »
Sinon, tu utilises un compilateur C++ et tu utilises std::string et ostringstream.

Comme beaucoup de compilos, Visual supporte partiellement le C99 (dans le cas de Visual C++, le support est vraiment limité). Donc, teste la fonction dont tu parles et tu verras bien.

J'ai la flemme de chercher, mais il existe plusieurs bibliothèques pour le C, tu peux en trouver une qui fournisse un type string.

Offline flure

  • Base
    • Pouet.net
    • View Profile
  • Ancienneté: 1998
  • Groupe: PoPsY TeAm
  • Rôle: Codeur Linux
  • Ville: Lyon
Re : question de langage c.
« Reply #10 on: 13 July 2011 à 13:37:08 »
Mmmmh compiler du C en C++... Ça revient à faire du C++ sans utiliser les fonctionnalités du C++. Et, d'expérience, C et C++ sont deux langages très différents, il faut notamment s'attendre à des comportements différents au niveau des UB (bon ok c'est du pinaillage...).
Mais l'idéal serait quand même d'avoir une bonne lib qui gère les strings en C, parce c'est tout ce qui manque à ce super langage :)

Offline kernel_error

  • Base
    • Pouet.net
    • View Profile
    • wtflol
  • Rôle: code
Re : question de langage c.
« Reply #11 on: 13 July 2011 à 14:24:46 »
malloc (+realloc si necessaire) devrait suffir ? Ou bien j'ai rien compris ?

Offline flure

  • Base
    • Pouet.net
    • View Profile
  • Ancienneté: 1998
  • Groupe: PoPsY TeAm
  • Rôle: Codeur Linux
  • Ville: Lyon
Re : question de langage c.
« Reply #12 on: 13 July 2011 à 15:01:45 »
@kernel_error quand tu fais un sprintf, tu ne sais pas quelle taille aura la chaîne finale que tu vas mettre dans ton buffer, tu ne peux donc pas savoir à l'avance de combien l'allouer. Et du coup c'est très très peu sécure comme fonction.
exemple :
Code: [Select]
char buff[25];
sprintf(buff, "%s\n %s\n %d %s", "toto raconte une blague", "titi ne la trouve pas drôle", 2, "personnes ne rigolent pas");

Et boum parce que buff n'est pas assez grand. Encore là ça va parce qu'on connaît les tailles des chaînes qu'on va insérer dans buff, mais quand c'est de l'user input, tu n'as aucun moyen de le savoir à moins de faire plein de strlen avant et de malloc'er en conséquence. Bref c'est la solution que tu proposes, mais c'est ce qui fait que la gestion des chaînes en C est super chiante. D'où l'intérêt d'un type String à la Pascal et des fonctions qui vont bien pour encapsuler tout ça (concatenation, formattage, remplacement de sous-chaîne, etc. etc...).

Offline ponce

Re : question de langage c.
« Reply #13 on: 13 July 2011 à 19:38:42 »
Je me demande si des fois, std::string est optimisée pour les petites chaînes. Sous GCC, sizeof(std::string) donne 4 octets, sous MSVC 32 en debug et 28 en release. Perso je n'était pas fan des chaînes Pascal de 256b fixes.
Sinon les QString de Qt sont copy-on-write.

Offline flure

  • Base
    • Pouet.net
    • View Profile
  • Ancienneté: 1998
  • Groupe: PoPsY TeAm
  • Rôle: Codeur Linux
  • Ville: Lyon
Re : question de langage c.
« Reply #14 on: 14 July 2011 à 06:00:35 »
@ponse std::string ça reste du C++ quand même.
Sinon pour Pascal tu parles sûrement des ShortString, qui ont depuis longtemps été remplacées par les AnsiString et WidesString (en fait c'est String mais tu choisis l'une au l'autre par une option du compilo) qui n'ont pas cette limitation.

Mais sinon, dès qu'on utilise un objet pour un type basique comme la String, c'est difficile à mon avis de faire ça de manière optimale. Soit on fait ça comme en C et dans ce cas l'utilisateur (le programmeur) doit tout faire à la mano, soit on utilise un objet, genre une structure qui contient le tableau de char et sa longueur, et ptetre d'autres infos, et un ensemble de fonctions pour manipuler cet objet (un ADT quoi, comme pour le type FILE), et dans ce cas forcément le coût mémoire est plus important. Mais bon, AMHA dès qu'on a besoin d'un tel objet pour manipuler des chaînes, c'est que le coût mémoire importe peu, en tout cas on n'est pas à 32 octets près.
« Last Edit: 14 July 2011 à 06:04:16 by flure »