URL: https://linuxfr.org/forums/programmation-c--2/posts/hack-de-vfscanf3-4-questions Title: Hack de vfscanf(3), 4 questions Authors: JaguarWan Date: 2006年01月02日T06:46:44+01:00 Tags: Score: 0 Bonjour :) Pour les besoins d'un projet, j'ai eu envie de bidouiller vfscanf pour l'adapter à mes besoins. J'ai quasi fini mon bidouillage mais j'ai quatre questions : * de base mon snscanf ne travaille que sur des buffers, y aurait-il un moyen portable d'encapsuler des buffers dans des FILE * (en dehors de l'extension GNU fmemopen() pas portable du tout) pour que je puisse le généraliser aux fichiers ? * J'ai ajouté la lecture de données binaires, mais je suis pas très content de ma fonction de conversion... Auriez vous des idées pour optimiser cette chose (particulièrement la boucle moche octet par octet) ? (testée sous Linusque x86 et OS X sur PearPC): static unsigned long long _fetch_int(const u_char *b, size_t w, int flags) { long long ret = 1; £spaces£ £/spaces£int sys_endian = 0; /* 0 == big endian, little endian otherwise */ £spaces£ £/spaces£if ( (ret = 1) && (*(char *) & ret) == 1) sys_endian = 1; £spaces£ £/spaces£if (flags & BIG) sys_endian = 0; else if (flags & LITTLE) sys_endian = 1; £spaces£ £/spaces£if (flags & TRUNK) { £spaces£ £/spaces£if ( £spaces£ £/spaces£(sys_endian == 1 && (flags & HIBYTES)) || £spaces£ £/spaces£(sys_endian == 0 && (flags & LOBYTES)) £spaces£ £/spaces£) { £spaces£ £/spaces£/* should begin from the MSB */ £spaces£ £/spaces£[...] gros tas de if pour se placer à la fin du buffer [...] £spaces£ £/spaces£b -= w; £spaces£ £/spaces£} £spaces£ £/spaces£} £spaces£ £/spaces£ret = 0; £spaces£ £/spaces£/* fetch bytes, storing them using the given endianness */ £spaces£ £/spaces£if (sys_endian) { £spaces£ £/spaces£while (w --) ret += (long long) b[w] << w * 8; £spaces£ £/spaces£} else { £spaces£ £/spaces£size_t i = 0; £spaces£ £/spaces£while (w --) ret += (long long) b[w] << (i ++ * 8); £spaces£ £/spaces£} £spaces£ £/spaces£return ret; } * Enfin, le meilleur pour la fin: l'équivalent en floating point ne marche pas... quand je caste b[w] en long double, j'ai gcc qui se roule en position foetale et couine "error: invalid operands to binary <<"... J'ai aussi un "invalid storage class" pour _fetch_float() (la même chose qu'au dessus mais avec des casts en fait :) ) si je lui fait renvoyer un long double... Et de surcroît, dès que je caste mes binaires en float/double ils deviennent tout corrompu de l'intérieur, alors que si je me contente de les copier en tant qu'entier ça passe ! En fait: memcpy(buf, & monfloat, sizeof(monfloat)); snscanf(buf, sizeof(buf), "%bf", & monfloat); /* foire */ alors que: snscanf(buf, sizeof(buf), "%bi", & monfloat); /* marche */ et c'est le même code path aux casts près ø_ø Le code source du bousin complet est là: [http://mammouth.tuxfamily.org/vfscanf.c](http://mammouth.tuxfamily.org/vfscanf.c) Merci d'avoir tout lu, et merci d'avance pour vos réponses :)

AltStyle によって変換されたページ (->オリジナル) /