Toujours les structures / Accès direct [C/C++] - C++ - Programmation
Marsh Posté le 17-02-2005 à 08:27:12
ben à partir du moment où tu le places dans une structure autant y accèder comme tel non?
Sinon tu peux faire une gruikerie via le préprocesseur
Code :
|
En ayant pris soin de définir repertoire_struct comme de type struct repertoire
Marsh Posté le 17-02-2005 à 09:57:46
Mon problème est que les structures sont énormes et servent à rappatrier des données en masse venues de fichiers (parfois 400 champs dans ma structure)
L'objectif est de pouvoir détecter le nom du champ numéro 50 de ma structure par exemple
pour y accéder (syntaxe érronée bien sur, je ne la connais pas)
repertoire.[nom_champ[20]];
nom_champ n'étant pas un tableau mais une éventuelle fonction de la STL ou autre...
Si ca existe ca serait l'occasion de me faire gagner 100 ans de code
Marsh Posté le 17-02-2005 à 10:00:44
400 champs dans une struct ?
(cela dit j'ai pas compris ce que tu veux faire exactement, faudrait que tu decrives un peu mieux ton but)
Marsh Posté le 17-02-2005 à 10:08:53
J'ai pas non plus trop compris le but de la manoeuvre mais à priori tu peux peut etre utiliser une table de hashage (hsearch, hcreate, hdestroy) ou les dbm si tu es sous Unix. Ca fonctionne sur le shemà cle unique/valeur ce qu'il me semble que tu cherches.
Marsh Posté le 17-02-2005 à 10:10:43
manatane > t'as pas plutot une hashmap C++ ? (sous VS je sais que c'est stdext::hash_map (ils l'ont sorti de std pour des raisons de norme, je sais pas ce qu'il en est sous gcc))
Marsh Posté le 17-02-2005 à 10:23:51
en fait çà dépend de la version de gcc : à partir de gcc 3.2
the include file hash_map of gcc 2.95.2 has become ext/hashmap On top of that, the type is no more std::hash_map but __gcc_cxx::hash_map. One way of dealing with that is to use hash_map (without a namespace) and do this for inclusion :
Code :
|
Marsh Posté le 17-02-2005 à 10:25:16
__gnu_cxx
zaurais pu trouver un peu plus sesksy quand meme
Marsh Posté le 17-02-2005 à 10:30:22
Les mecs de gcc savent rire http://www.djmnet.org/humor/gcc-pragma.txt
Marsh Posté le 17-02-2005 à 11:09:02
J'explique, le domaine est un peu "très pointu" donc je ne peux pas aller dans les détails :
Je recois des messages et j'en envoie, ces messages ont une structure très particulière (des short, des long, des float etc)
J'ai créé la dizaine de strucutres types pour les envois/receptions de messages
J'aimerais faire des affichages écran ou dans un fichier texte sans m'embeter à faire genre
cout << "Champ Adresse" << mastruct.Adresse;
Je voudrais pouvoir faire :
cout << "Champ " << mastruct.[Champ(1)] << " : " << mastruct.(mastruct.[Champ(1)]) << "endl";
Champ() étant la fonction que je cherche (si elle existe ou si elle est codable)
Voila ! je me suis peut etre mieux fait comprendre
Marsh Posté le 17-02-2005 à 11:24:31
J'ai pas tout compris sur le pourquoi tu veux faire ça (et pas utiliser bêtement une simple map).
Mais je pense que tu devrais regarder du côté des pointers to data members.
http://www.icce.rug.nl/documents/c [...] lus15.html
Marsh Posté le 17-02-2005 à 11:31:04
bin ca l'aidera pas, si je comprends bien il aimerait aussi avoir le nom du champ gratuitement
Marsh Posté le 17-02-2005 à 11:34:36
Bah, tu utilises une vielle macro moisie, qui te pond à la fois le symbole et son nom...
Genre:
Code :
|
Marsh Posté le 17-02-2005 à 13:03:49
plus simple éventuellement :
Est il possible de créer une structure, avec pour noms de champ des variables ? ou éventuellement des const char * ou const string ?
La syntaxe est encore fausse :
Code :
|
je n'ai pas le compilo sur le PC ou j'ai internet, donc je ne peux pas tester ! Ca fonctionne ce genre de choses ? Ou alors y a-t-il une syntaxe différente permettant de donner des noms de champs appartenant à une variable ?
Marsh Posté le 17-02-2005 à 13:51:26
Et si tu essayé de faire les choses simplement et de façon propre?
Parce que tout ce tintamare pour un truc aussi con que çà c'est un peu bete. Celà je ne suis toujours pas sur d'avoir compris ce que tu veux faire...
Code :
|
Et puis essaie de connaitre le C avant de faire du C++.
Marsh Posté le 17-02-2005 à 14:01:18
Tu essaies de m'expliquer quoi là ?
Je sais bien déclarer une structure, mon problème est que j'aimerais par une méthode C ou C++, que les noms des champs de ma structures soient données par une autre variable.
Si ce n'est pas possible, tu me le dis et tu ne m'envoie pas des petites phrases assassines ridicules car ce que tu as écrit, je le sais très bien...
Tintamarre pour un truc aussi con : Tu es bien gentil, mais mes structures ce ne sont pas des structures à 3 champs avec toto & co. Ce sont une dizaine de structure avec parfois des 100aines de champs. Je les utilises car j'ai besoin de faire de la lecture/écriture en bloc.
J'ai été poli pdt tout le topic que je sache
Marsh Posté le 17-02-2005 à 14:11:53
kowalski a écrit : Tu essaies de m'expliquer quoi là ? |
Citation : Est il possible de créer une structure, avec pour noms de champ des variables ? ou éventuellement des const char * ou const string ? |
Citation : Tu es bien gentil, mais mes structures ce ne sont pas des structures à 3 champs avec toto & co. Ce sont une dizaine de structure avec parfois des 100aines de champs. Je les utilises car j'ai besoin de faire de la lecture/écriture en bloc. |
A ben ouais évidemment...
Citation : J'ai été poli pdt tout le topic que je sache |
Ben heureusement et moi aussi j'étais poli.
Marsh Posté le 17-02-2005 à 14:19:23
Je n'insiste pas, amuse toi bien cette après midi, moi j'ai du travail.
Si tu n'as pas compris ce que je demandais (même si je ne m'exprime pas selon la norme ANSI/ISO), et bien tant pis pour moi.
Je veux SOIT récuperer le NOM d'un champ en spécifiant sa POSITION, et pas sa VALEUR.
SOIT créer une structure dont les NOMS des champs sont nommés par des VARIABLES.
Pour ensuite faire : Mastructure.MesChamps[5] Pour accéder au 5e champ de ma structure. (Bien que ce ne soit pas possible selon cette syntaxe, voilà pourquoi je suis là, en train de vous demander une solution)
Si je trouve mon bonheur je mettrais la réponse ici
Merci chrisbk.
Marsh Posté le 17-02-2005 à 14:28:04
kowalski a écrit : |
pas trop possible, voir meme je vois pas trop, au débotté. Je fricotte jamais avec des structs de 200membres, ca depasse rarement la dizaine (au dela c'est que generalement j'ai merdé qqpart)
kowalski a écrit : |
bin pour ca t'as la solution table de hachage.
Genre (en c++, vu que t'as mis ton topic en cat c++)
matabledehachage["roger"] = 15;
matabledehachage["simone"] = 22;
pomme = matabledehachage["pack de kro"]
par contre, ca te dezingue ton ecriture en bloc (mais bon, tu peux t'y retrouver en faisant une iteration sur ta table de hachage) et une table de hachage ne peut contenir qu'un type (soit int, soit float, soit une structure mais pas un mélange)
evidemment, tu peux bricoler un truc genre
Code :
|
et stocker des "Valeurs" dans ta tdh. Mais jtrouve pas que ca casse des briques. (vu que t'es en c++ tu peux planquer tout ca dans une classe, et planquer un brin le tout avec une surcharge d'operateur, mais bon, idem)
(ou alors faire plusieurs tds, stockée dans une struct, une par type)
Marsh Posté le 17-02-2005 à 14:37:25
Merci beaucoup, mais effectivement (pour le 2e cas que tu as explicité) je pense que je préfère faire une écriture/lecture en bloc qu'un accès aux champs.
La chose c'est que je ne peux pas réduire mes structures, elles sont données par un fabricant, et bien sur celui ci n'a pas mis dans l'ordre float avec float, short avec short etc... Tout est mêlé à l'intérieur ce qui fait des structs immenses...
Accéder au nom du champ a l'air impossible mais ca m'aurait permis de gagner un nombre de ligne incroyable et surtout de permettre aux gens qui reprendront le code de mettre à jour facilement sans avoir à modifier l'IHM du prog...
Je vais tenter de faire le truc le plus propre possible avec des struct, ca m'emmerde mais c'est comme ca...
Question subsidiaire. Imaginons que je crée en parallèle une map avec un #id et "les noms de champs"
Je fais une structure déclarée normalement (donc avec les noms des champs explicités) mais lors de l'appel des champs, j'utilise ma map, du genre :
MaStructure.Mamap<21>
Avec Mamap<21> qui contient le nom du champ !
Bon j'espère que je n'insiste pas trop avec ca...
Marsh Posté le 17-02-2005 à 18:29:36
Mon problème je pense est que j'ai de bonnes notions de quelques langages mais que je ne suis expert dans aucun...
En PHP, je peux appeller une variable comme cela :
$["mavariable_$compteur"] lorsque $compteur est à 20, ca accède à $mavariable_20.
Existe-t-il en C ou C++ un opérateur proche de [] en PHP ? ca pourrait résoudre mon probleme
Marsh Posté le 17-02-2005 à 18:40:24
bin une hashmap int -> truc
le pb c'est que le C/C++ sont fortement (pas de dialogue d'expert la dessus plz) donc fo connaitre a l'avance 'truc' precisemment
Marsh Posté le 17-02-2005 à 18:48:35
Oui, mais avec une map je ne pense pas pouvoir accéder à un champ d'une structure... Enfin en tourne en rond
Merci de ton aide, et si tu as un éclair de génie... !
Marsh Posté le 17-02-2005 à 19:12:11
kowalski a écrit : Oui, mais avec une map je ne pense pas pouvoir accéder à un champ d'une structure... Enfin en tourne en rond |
kowalski a écrit : Oui, mais avec une map je ne pense pas pouvoir accéder à un champ d'une structure... Enfin en tourne en rond |
Pourquoi ne pas utiliser une "union", avec un truc style
Code :
|
Evidemment c'est un peu tordu mais je vois que ça...
Marsh Posté le 17-02-2005 à 19:48:22
C'est tordu certes, mais c'est pas mal !
Lors de la lecture, je peux utiliser un compteur pour incrémenter zone à ton avis et éviter d'écrire
grosTruc.zone1
grosTruc.zone2
grosTruc.zone3 ?
Si oui, c'est la solution j'imagine
Marsh Posté le 17-02-2005 à 22:22:49
kowalski a écrit : C'est tordu certes, mais c'est pas mal ! |
Déjà, c'est pas "grosTruc.zone1" mais "grosTruc.champ.zone1".
En fait, (et contrairement à tous les autres qui ont répondu un peu au pif) je comprends ton problème. Tu as une structure tellement énorme que tu dois traiter champ par champ (probablement l'afficher) et ça te fait chier de coder 4000 "printf" pour les 4000 champs de ta structure. Donc tu aimerais faire un "for (i=0; i < 4000; i++)" et juste faire "grosTruc.champ.zone[i] >> cout" (où un truc analogue)
Désolé, je trouve pas. Si les champs ne sont pas identique, je crois pas cela possible. J'essaye d'imaginer un pointeur qui irait de champ en champ mais avec des champs de taille différente, (et peut-être même mélange joyeux de char[] avec des double) jtrouve pas l'idée géniale. Désolé...
Peut-être faut revoir ta conception. Pourquoi faire tant de champ si le traitement doit être analogue pour chacun ? Pourquoi pas un gros tableau de choses identiques à la place ? En fait j'ai jamais eu ce problème.
Autre solution: Créer un générateur de script qui analyse ta structure et génère les 4000 "cout". Puis tu insères ces lignes dasn ton source.
Encore désolé...
Marsh Posté le 17-02-2005 à 22:27:05
Ce n'est pas à toi de t'excuser !
Merci en tous cas pour ta contribution
Je me disais que le préprocesseur avait quelques fonctions permettant de naviguer dans les structures...
Pour la conception, comme expliqué, je n'ai pas trop le choix, c'est un choix constructure, je dois piloter du matériel...
bref, je crois que je vais me tapper du cout (et pas seulement d'ailleurs)
Vais passer ma nuit sur msdn...
Bonne nuit
Marsh Posté le 18-02-2005 à 11:10:57
kowalski a écrit : Ce n'est pas à toi de t'excuser ! |
J'ai trouvé un truc qui peut t'aider
1) j'ai imaginé une fonction qui affiche chaque champ (une fonction par champ) et un tableau de fonctions qui stocke toutes les fonctions nommées
Voilà ce que ça donne (écrit en norme C paske suis pas assez calé en C++ pour le faire en C++)
Code :
|
Ensuite, je me suis dit que ton traitement n'est pas forcément un bête affichage et je me suis donc demandé si je pouvais pas juste récupérer la valeur de chaque champ en laissant le traitement de coté.
Donc il me fallait faire une fonction qui renvoie chaque champ. Là, j'avais un problème parce que les champs sont de type différents. Alors j'ai pensé à renvoyer un pointeur sur le champ plutôt que la valeur du champ lui-même. Sauf que le pointeur que tu récupères faut ensuite que tu saches ce que c'est pour savoir comment t'en servir. Alors j'ai pensé à associer à chaque fonction un flag indiquant le type de pointeur renvoyé.
Voilà le résultat:
Code :
|
Ca fonctionne... mais ça devient "usine à gaz". Déjà rien que pour relire les parenthèses (qui sont toutes obligatoires du fait des priorités) tu te prends la tête. T'as vâchement intérêt à mettre beaucoup de commentaires parce que dans 6 mois, si tu reviens sur ton pgm; ben tu te tireras une balle !!!
A+
Marsh Posté le 18-02-2005 à 11:17:44
LOOOL ! Tu viens de lire mon PM ? c'est en gros ce que je tente de faire, sauf que ca me parait moins lourd de mon coté avec mes 2 maps
Je compare et je vous tiens au courant !
Marsh Posté le 18-02-2005 à 11:18:44
Ah non en fait c'est pas vraiment pareil, je n'ai pas une fonction par champ de mon coté avec mon arithmétique de pointeurs je peux également modifier les valeurs...
Tu penses que quelle solution est la plus viable et / ou maintenable ?
Marsh Posté le 18-02-2005 à 11:27:27
kowalski a écrit : Ah non en fait c'est pas vraiment pareil, je n'ai pas une fonction par champ de mon coté avec mon arithmétique de pointeurs je peux également modifier les valeurs... |
Hum... j'ai pas pensé à "comment modifier les valeurs".
A mon avis, ta solution est la meilleure puisque de mon coté, avec 4000 champs je dois coder 4000 "get...".
J'avais aussi envisagé l'arithmétique des pointeurs mais je voyais pas trop comment imaginer le truc. Poste donc ton code que je regarde comment tu as fais ???
Marsh Posté le 18-02-2005 à 11:32:05
Je poste d'ici 1h éventuellement because là, j'ai encore qq étonnements sur la place mémoire des données dans ma struct, j'ai l'impression que même si j'ai qqch de 16b, il décalle de 32 pour le champ suivant, c'est étrange...
Je poste dans l'aprem
Marsh Posté le 18-02-2005 à 11:35:42
kowalski a écrit : Je poste d'ici 1h éventuellement because là, j'ai encore qq étonnements sur la place mémoire des données dans ma struct, j'ai l'impression que même si j'ai qqch de 16b, il décalle de 32 pour le champ suivant, c'est étrange... |
nonon c'est pas etonnant, il aligne les données, j'avais fait un pety cours la dessus, attends vouar
Marsh Posté le 18-02-2005 à 11:36:45
kowalski a écrit : Je poste d'ici 1h éventuellement because là, j'ai encore qq étonnements sur la place mémoire des données dans ma struct, j'ai l'impression que même si j'ai qqch de 16b, il décalle de 32 pour le champ suivant, c'est étrange... |
Il est possible que ton optimiseur de code s'arrange pour que la taille de ta structure fasse pile poil un nombre puissance de 2. En effet, le C arrive vâchement mieux à gérer les structures qui ont une taille égale à une puissance de 2...
A+
Marsh Posté le 18-02-2005 à 11:38:23
Il n'y aurait pas qqch à décocher pour éviter ca ?
Par exemple j'ai un short entouré par des long
le short prend 32 bits !
ensuie j'ai plusieurs short à la suite
le short prend 16 bits...
C'est étrange non ?
Marsh Posté le 18-02-2005 à 11:38:55
vala j'avais ecrit ca pour un pro du fortran
Si tu veux acceder rapidement a une donnée de 8octets, par exemple, ca va plus vite si son adresse%8 = 0. (ceci est un fait)
Pour celle de 4 octets, c'est %4
logique.
Bon, prenons une structure, avec des membres, genre
Code :
|
la comme j'ai fait, c'est mal, parce que si le compilo aligne monInt sur une adresse %4, il sera obligé de foutre 4octets de padding apres monInt pour que monDouble soit aligné sur une %8. C'est con.
alors que si j'avais fait :
Code :
|
bin la ca aurait été bon. Il aligne monDouble sur une %8, monInt est forcement bien aligné(vu que si truc%8=0 alors (truc+8)%4=0, n'est ce pas ?), et monChar pareil. On apelle ca l'alignement naturel.
Bref, dans une struct, faut tjs mettre les plus grand membre devant, apres les petits, etc etc...
et donc a priori ton compilo aligne pour toi
Marsh Posté le 18-02-2005 à 11:43:27
En québécois je dirais : osti de cibouère de Caliss !
Bon, ca ne m'arrange vraiment pas tout ca. Mon compilateur actuel ne sera pas mon compilateur que j'utiliserais à la fin (ma boite m'a pas encore filé VS, j'utilise DEvC++ en attendant)
Si ce genre de chose sont désactivables sous VS, je mets ca de coté et je fais autre chose...
Par exemple chez moi :
long 32b
short 32b
long 32b
long 32b
short 16b
short 16b
short 16b
short 16b
C'est stressant parce que ma logique fonctionnait
Marsh Posté le 18-02-2005 à 11:45:09
Je comprends tout à fait que les accès mémoires sont facilités, mais je ne cherche pas la perfo là mais la simplicité de code
Sinon, je ne peux évidemment pas changer l'allure de mes struct (sinon ca fait longtemps que ce serait fait )
Marsh Posté le 18-02-2005 à 11:47:38
c'est desactivable en fonction du compilo, genre
#pragma pack(1)
typedef struct {
...
}
#pragma pack()
mais ca implique de recompiler TOUT ce qui utilise cette struct
Marsh Posté le 18-02-2005 à 11:52:59
Bon eh bien je ne sais pas quoi vous dire
Merci serait approprié...
Je vous tiens au courant et je posterais une version standard tu code
Marsh Posté le 17-02-2005 à 08:04:13
admettons que nous ayons :
Est-il possible d'accéder au champ 2 sans spécifier que celui ci s'appelle telephone ?
Ce que j'aimerais afficher c'est :
telephone : 025485254 ; sans spécifier le nom du champ
En somme je cherche surtout le moyen de d'accéder au nom d'un champ dans une structure, en connaissant sa place dans la structure de donnée