Variables de struct dans un tableau - C
Résolu/Fermé
siskozed
Messages postés
69
Date d'inscription
mercredi 16 janvier 2008
Statut
Membre
Dernière intervention
2 septembre 2009
-
5 mai 2008 à 11:04
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 - 9 mai 2008 à 08:01
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 - 9 mai 2008 à 08:01
A voir également:
- Variables de struct dans un tableau - C
- Tableau word - Guide
- Tableau croisé dynamique - Guide
- Tableau ascii - Guide
- Trier un tableau excel - Guide
- Comment imprimer un tableau excel sur une seule page - Guide
19 réponses
siskozed
Messages postés
69
Date d'inscription
mercredi 16 janvier 2008
Statut
Membre
Dernière intervention
2 septembre 2009
86
6 mai 2008 à 10:48
6 mai 2008 à 10:48
je ne mettais pas le code exprès dans le but que vous réflechissiez simplement sur ma facon de procéder. En effet, je suis passé par la piste des sprintf et c'est bon désormais.
Voici le code intégrale si ca vous interesse :
FICHIER.C
fichier.h
Voici le code intégrale si ca vous interesse :
FICHIER.C
#include "FOSSIL.H" #include "CLIB.H" #include <dos.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "primsolclimat_server.h" //*-+*-+*-+*-+*-+*-+*-+*-+*-+*-+*-+*-+*-+*-+*-+*-+*-+*-+*-+*-+*-+*-+*-+*-+*-+*-+ int main() { printf( "-- PRIMSOL CLIMAT - L.BERNARD - 2008 --\n\n"); initialiser(); communicationSocket(); analyserTrame(); return 0; } void initialiser() { // initialisation baudrate ------------------------------------ fossil_setbaud(0,9600, FOSSIL_PARITY_NO, 8, 1); pfe_enable_pio (10,5); // initialise pio10 en sortie au niveau bas pfe_enable_pio (9,1); // initialise pio9 en entrée pour qu'il soit capable // de lire avant d'émettre sleep(1); // purge des buffers entrée et sortie fossil_purge_output( 0 ); fossil_purge_input( 0 ); retStatu1 = fossil_status_request ( 0 ); if ((retStatu1 && 0x40) == 1 ) // test du bit 6 Buffer vide { printf( "\rLe buffer est vide\n") ; } else { printf( "\rProbleme, le buffer devrait etre vide\n"); } } void huge creerSocket(void) { /*1 Initialisation de la socket locale d'écoute */ /*2 Création de la socket locale d'écoute */ /*3 Attachement des paramètres de la socket locale d'écoute */ /*4 Mise en écoute de la socket locale d'écoute */ /*5 Acceptation et mise en attente de connexion d'un client */ /*6 Réception du message de l'application cliente */ /*7 Envoi d'un message à l'application cliente */ /*8 Fermeture des sockets d'écoute et de communication */ //1 parametreListenSocket.sin_family = AF_INET; parametreListenSocket.sin_port = htons(PORT); parametreListenSocket.sin_addr.s_addr = 0; //2 // Création de la socket ListenServerSocket = opensocket(SOCK_STREAM, &Erreur); //3 Retval = bind(ListenServerSocket, (const struct sockaddr far *)¶metreListenSocket , &Erreur); //4 //mise en écoute de la socket d'ecoute Retval = listen(ListenServerSocket, 1, &Erreur); // Envoie d' "Hello world !\r\n" à n'importe quelle connection while(1) { if((CommServerSocket = accept(ListenServerSocket, (struct sockaddr *)¶metreCommSocket, &Erreur)) != 0) { send(CommServerSocket, &trame, 50, MSG_BLOCKING, &Erreur); } } } void communicationSocket(void) { RTX_Create_Task(&creerSocketId, &creerSocketDefBlock); } void huge timeout(void) { timer =0; printf("Chronometre :"); do { RTX_Sleep_Time(1000); timer++; printf("%i, ",timer); }while((timer!=30) && (flag!=1)); if(flag==1) { printf("\nMerci de verifier que la station est bien sous tension et qu'elle est connectee a la carte par un cable croise NULL MODEM "); } } void analyserTrame() { // reception et analyse de la trame----------------------------------------- do { flag = 0; RTX_Create_Task(&timeoutId, &timeoutDefBlock); i = 0; dummy = fossil_getbyte_wait ( 0 ); // le getbyte_wait récupere les octets //envoyés par liaison RS232 flag = 1; RTX_Delete_Task(timeoutId); meteobuffer[i] = dummy; if(meteobuffer[0]==0xff) // ON TESTE SI ON A RECU L'EN-TETE FF 1 FOIS { printf( "\n<%x>",meteobuffer[i]) ; // On affiche le premier octet recu i++; dummy = fossil_getbyte_wait ( 0 ); meteobuffer[i] = dummy; printf( "<%x>",meteobuffer[i]) ; // On affiche le deuxieme octet recu if(meteobuffer[1]==0xff) // ON TESTE SI ON A RECU FF 2 FOIS {//si on a recu <ff> <ff>, on analyse le troisieme octet pour définir le type de mesure i++; dummy = fossil_getbyte_wait ( 0 ); meteobuffer[i] = dummy; printf( "<%x>",meteobuffer[i]) ; // On affiche le 3eme octet recu switch (meteobuffer[2]) // en fonction de meteobuffer[2] { /////////////////////// VENT /////////////////////////// case 0: // on en deduit que c'est le vent j = 10; // boucle pour récupérer les mesures du vent do { i++; dummy = fossil_getbyte_wait ( 0 ); meteobuffer[i] = dummy; printf( "<%x>",meteobuffer[i]) ; // On affiche l'octet recu }while (i < j); //printf( "\n Grandeur mesuree : "<< grandeur << "\n\n"; printf( "\nC'est le vent\n"); //////////////////////// Rafales et vitesse moyenne //////// capteur_station.vrafvent2 = (meteobuffer[5]&0xf0)>>4; capteur_station.vrafvent = meteobuffer[6]&0x0f+((meteobuffer[6]&0xf0)>>4)*10; /////////////// Direction du vent exprimee en ° ////////////// capteur_station.dvent = (meteobuffer[4]&0x0f)+((meteobuffer[4]&0xf0)>>4)*10 +(meteobuffer[5]&0x0f)*100; printf( "Vitesse des rafales : %i,%i\nDirection du vent : %i\n", capteur_station.vrafvent,capteur_station.vrafvent2,capteur_station.dvent ); break; /////////////////////// PLUIE /////////////////////////// case 1: j = 15; // on en deduit que c'est la pluie // boucle pour récupérer les mesures de la pluie do { i++; dummy = fossil_getbyte_wait ( 0 ); meteobuffer[i] = dummy; //conversion en hexadecimal printf( "<%x>",meteobuffer[i]) ; // On affiche l'octet recu }while (i < j); printf( "\nC'est la pluie\n"); //////////////////////// pluviometrie en mm/h /////////////// capteur_station.pluv = (meteobuffer[4]&0x0f)+((meteobuffer[4]&0xf0)>>4)*10+(meteobuffer[5]&0x0f)*100; printf( "Pluviometrie : %i mm/h\n", capteur_station.pluv) ; break; /////////////////////// THERMO, HYGRO /////////////////////// case 3: j =8; // on en deduit que c'est la temperature et l'hygrometrie // boucle pour récupérer les mesures do { i++; dummy = fossil_getbyte_wait ( 0 ); meteobuffer[i] = dummy; //conversion en hexadecimal printf( "<%x>",meteobuffer[i]) ; // On affiche l'octet recu }while (i < j); //printf( "\n Grandeur mesuree : " << grandeur <<"\n\n" ; printf( "\nC'est la temperature et l'hygrometrie\n"); capteur_station.signe =(meteobuffer[5]&0x0f)>>7; if (capteur_station.signe==0) { signe = "+"; } else { signe = "-"; } capteur_station.temp =((meteobuffer[4]&0xf0)>>4)+(meteobuffer[5]&0x0f)*10+((meteobuffer[5]&0x30)>>4)*100; capteur_station.temp2 =(meteobuffer[4]&0x0f); printf( "Temperature : %s %i,%i Degres Celsius\n", signe, capteur_station.temp, capteur_station.temp2 ); capteur_station.hygr =(meteobuffer[6]&0x0f)+((meteobuffer[6]&0xf0)>>4)*10; printf( "Hygrometrie : %i pourcent\n", capteur_station.hygr ); break; case 6: j =13; // on en deduit qu'on ne traite pas cette grandeur // boucle pour récupérer les mesures do { i++; dummy = fossil_getbyte_wait ( 0 ); meteobuffer[i] = dummy; }while (i < j); printf( "\nOn ne traite pas cette grandeur\n"); break; case 14: j =4; // on en deduit qu'on ne traite pas cette grandeur // boucle pour récupérer les mesures do { i++; dummy = fossil_getbyte_wait ( 0 ); meteobuffer[i] = dummy; }while (i < j); printf( "\nOn ne traite pas cette grandeur\n"); break; default: // on en deduit que c'est une grandeur que l'on ne traite pas printf( "\nOn ne traite pas cette grandeur\n"); break; }; // fin switch case } else { printf("\nDesynchronisation de la trame a partir du deuxieme octet. La station meteo se synchronise. Si le processus dure plus d'une minute, merci de redemarrer la station meteo.\n"); }// fin else (if recup2 != ff) } else { printf("\nDesynchronisation de la trame des le 1er octet. La station meteo se synchronise. Si le processus dure plus d'une minute, merci de redemarrer la station meteo.\n"); } // fin else (if recup != ff) // création de la trame sprintf(trame, "%2i%2i%3i%2i%2i%2i%2i%3i", capteur_station.vrafvent , capteur_station.vrafvent2 , capteur_station.dvent , capteur_station.temp , capteur_station.temp2 , capteur_station.signe , capteur_station.hygr , capteur_station.pluv ); ; } // fin do-while general while(1); // L'application grâce à une boucle infinie ecoute toujours le port Serie EXT du DK51 }
fichier.h
#ifndef PRIMSOLSERVER_H #define PRIMSOLSERVER_H #include <stdlib.h> #include <stdio.h> #include <time.h> #include <dos.h> #include <windows.h> /****************************************************************************** * Constants ******************************************************************************/ #define TASKSTACKSIZE 2048 // Size of stack for created tasks in bytes #define PORT 4000 /****************************************************************************** * Prototypes ******************************************************************************/ void initialiser(void) ; void communicationSocket(void) ; void huge creerSocket(void) ; void huge timeout(void) ; void analyserTrame(void); /****************************************************************************** * Global variables ******************************************************************************/ /*///////////////////////////////////////////////////////////////////////////// variables pour la fonction d'analyse de la trame /////////////////////////////////////////////////////////////////////////////*/ int retStatu1; int i; int j; int a; unsigned char dummy; unsigned char meteobuffer[16]; unsigned char Var[2]; unsigned char * grandeur ; char* signe ; // structure de stockage des mesures struct capteur_station_tag { int vrafvent; // vitesse des rafales du vent int vrafvent2; // rafales du vent 0.1 digit int dvent; // direction du vent exprimee en °C int temp; // temperature int temp2; // temperature 0.1 digit int signe; // signe temperature int hygr; // hygrometrie int pluv; // pluviometrie }capteur_station; /*///////////////////////////////////////////////////////////////////////////// variables pour le thread de vérification de communication avec la station météo /////////////////////////////////////////////////////////////////////////////*/ int timeoutId; // ID du thread timeout qui verifie la reception de messages dans un delai acceptable int timer; int flag; unsigned int timeoutStack[TASKSTACKSIZE/sizeof(unsigned int)]; // pile TaskDefBlock timeoutDefBlock = { timeout, // Function to be executed in the task {'T','I','M','E'}, // Nom de la tache &timeoutStack[TASKSTACKSIZE/sizeof(unsigned int)], // Top of stack TASKSTACKSIZE, // Size of the stack 0, // Not supported 26, // Normal priority 0, // Time slice (not needed here) 0, 0, 0, 0 // Mailbox depth (not needed here) }; // Information on task 1 /*///////////////////////////////////////////////////////////////////////////// variables pour le thread de création de la communication socket /////////////////////////////////////////////////////////////////////////////*/ int creerSocketId; // ID du thread de creation de la communication par socket unsigned int creerSocketStack[TASKSTACKSIZE/sizeof(unsigned int)]; // pile TaskDefBlock creerSocketDefBlock = { creerSocket, // fonction qui va etre lancee par le thread {'S','O','C','K'}, // Nom de la tache &creerSocketStack[TASKSTACKSIZE/sizeof(unsigned int)], // Top of stack TASKSTACKSIZE, // Size of the stack 0, // Not supported 26, // Normal priority 0, // Time slice (not needed here) 0, 0, 0, 0 // Mailbox depth (not needed here) }; // Information on task 1 /*///////////////////////////////////////////////////////////////////////////// variables pour la communication par socket /////////////////////////////////////////////////////////////////////////////*/ // descripteurs de sockets (ecoute et comm) int ListenServerSocket; int CommServerSocket; // variable de traitement int Erreur; int Retval; char trame[9]; // represente la trame que l'on va envoyer au client // Enregistrements des parametres des sockets struct sockaddr_in parametreListenSocket; struct sockaddr_in parametreCommSocket; #endif
damlegone32
Messages postés
74
Date d'inscription
lundi 11 septembre 2006
Statut
Membre
Dernière intervention
31 mai 2011
29
5 mai 2008 à 14:08
5 mai 2008 à 14:08
Salut,
Moi je ferai un memcpy(&Trame[0],&(mastruct.variable0),n) avec n = 2 (octet) pour les int et n =4 pour le float.
Le problème avec cette solution c'est que tu copies des entiers qui tiennent sur 2 octets en mémoire dans des float qui tiennent sur quatres.
Je pense donc qu'il faut initialiser tes variables à 0 et peut être même commencer à copier les entiers a partir du deuxième octet du float : memcpy(&Trame[0]+2,&(mastruct.variable0),2). Tout dépend comment sont rangé les floats en mémoire (le poids fort est-il sur le premier octet ou pas)). Essaye les deux solutions et tu verras.
Peut être aussi qu'aucune des 2 ne marche...
A+
Moi je ferai un memcpy(&Trame[0],&(mastruct.variable0),n) avec n = 2 (octet) pour les int et n =4 pour le float.
Le problème avec cette solution c'est que tu copies des entiers qui tiennent sur 2 octets en mémoire dans des float qui tiennent sur quatres.
Je pense donc qu'il faut initialiser tes variables à 0 et peut être même commencer à copier les entiers a partir du deuxième octet du float : memcpy(&Trame[0]+2,&(mastruct.variable0),2). Tout dépend comment sont rangé les floats en mémoire (le poids fort est-il sur le premier octet ou pas)). Essaye les deux solutions et tu verras.
Peut être aussi qu'aucune des 2 ne marche...
A+
siskozed
Messages postés
69
Date d'inscription
mercredi 16 janvier 2008
Statut
Membre
Dernière intervention
2 septembre 2009
86
5 mai 2008 à 14:12
5 mai 2008 à 14:12
En fait, ca ca marche :
Ca servait à rien de se prendre la tete en fait...
Float trame[9] struct { int variable0 int variable1 … float variable7 int variable8 }mastruct; trame[0] = mastruct.variable0; trame[1] = mastruct.variable1 ; ... trame[7] = mastruct.variable7 ; trame[8] = mastruct.variable8 ;
Ca servait à rien de se prendre la tete en fait...
damlegone32
Messages postés
74
Date d'inscription
lundi 11 septembre 2006
Statut
Membre
Dernière intervention
31 mai 2011
29
5 mai 2008 à 14:23
5 mai 2008 à 14:23
Ah oui....
Pourquoi faire compliqué quand on peut faire simple...
Pourquoi faire compliqué quand on peut faire simple...
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
dubcek
Messages postés
18767
Date d'inscription
lundi 15 janvier 2007
Statut
Contributeur
Dernière intervention
5 mars 2025
5 628
5 mai 2008 à 14:37
5 mai 2008 à 14:37
mais l'int mastruct.variable0 a été converti en float trame[0]
damlegone32
Messages postés
74
Date d'inscription
lundi 11 septembre 2006
Statut
Membre
Dernière intervention
31 mai 2011
29
5 mai 2008 à 15:00
5 mai 2008 à 15:00
Ben oui normal...
Mais la valeur est la même non ?
Mais la valeur est la même non ?
dubcek
Messages postés
18767
Date d'inscription
lundi 15 janvier 2007
Statut
Contributeur
Dernière intervention
5 mars 2025
5 628
5 mai 2008 à 16:04
5 mai 2008 à 16:04
oui
siskozed
Messages postés
69
Date d'inscription
mercredi 16 janvier 2008
Statut
Membre
Dernière intervention
2 septembre 2009
86
6 mai 2008 à 09:42
6 mai 2008 à 09:42
je rencontre maintenant le bon probleme, ;)
Initialement, je voulais, à partir de mon serveur, envoyer une trame à mon client par une connexion via socket. J'avais pensé créer un tableau dans lequel j'aurais mis toutes les informations enregistrées initialement dans une structure.
Mais ca n'a pas l'air de marcher.
J'explique :
* je récupere avant : - la temperature
- la pluviometrie
- l'hygrometrie
- etc
- le vent
* j'enregistre tout ca dans mastructure.
* le serveur lance un thread qui va créer un socket d'ecoute et qui va le mettre à l'écoute des connexions
* un client va se connecter (toutes les 35 secondes)
* le serveur doit lui envoyer directement la trame...
Quelqu'un saurait ce qui cloche ?
Je pense qu'il faut que j'utilise sprintf mais je suis pas super doué là-dedans...grrrr
Initialement, je voulais, à partir de mon serveur, envoyer une trame à mon client par une connexion via socket. J'avais pensé créer un tableau dans lequel j'aurais mis toutes les informations enregistrées initialement dans une structure.
Mais ca n'a pas l'air de marcher.
J'explique :
* je récupere avant : - la temperature
- la pluviometrie
- l'hygrometrie
- etc
- le vent
* j'enregistre tout ca dans mastructure.
* le serveur lance un thread qui va créer un socket d'ecoute et qui va le mettre à l'écoute des connexions
* un client va se connecter (toutes les 35 secondes)
* le serveur doit lui envoyer directement la trame...
Quelqu'un saurait ce qui cloche ?
Je pense qu'il faut que j'utilise sprintf mais je suis pas super doué là-dedans...grrrr
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
6 mai 2008 à 10:20
6 mai 2008 à 10:20
vu que tu ne mets pas le code d'envoie, je ne voi pas comment on peut deviner ce qui cloche.
Mais si tu passes par les socket, je ne comprends pas la convertion de struct vers float[]...
Par contre, je ne suis pas d'accord avec damlegone32, la taille des float et des int dépend de l'implémentation du C (la machine+le système d'exploitation+ le compilateur) la spécification du ne donne que des tailles minimales.
Ce qui fait que les bidouilles sur les mémoires ne sont pas portable et sont donc fortement déconseiller.
Le mieux dans ces cas là, je dirai que c'est de faire un tableau :
void* trame;
et d'utiliser la commande sizeof() pour le remplir
trame = malloc(sizeof(mastruct));
Mais au final, autant conserver la structure.
Mais si tu passes par les socket, je ne comprends pas la convertion de struct vers float[]...
Par contre, je ne suis pas d'accord avec damlegone32, la taille des float et des int dépend de l'implémentation du C (la machine+le système d'exploitation+ le compilateur) la spécification du ne donne que des tailles minimales.
Ce qui fait que les bidouilles sur les mémoires ne sont pas portable et sont donc fortement déconseiller.
Le mieux dans ces cas là, je dirai que c'est de faire un tableau :
void* trame;
et d'utiliser la commande sizeof() pour le remplir
trame = malloc(sizeof(mastruct));
Mais au final, autant conserver la structure.
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
6 mai 2008 à 14:28
6 mai 2008 à 14:28
si j'ai demandé le code, c'est que je ne voyais rien d'anormal dans ta porcédure, et, c'est que je suspectait une erreur dans le send. Ce qui d'ailleurs n'est peut être pas faux. Si tu regarde ici : http://www.linux-kheops.com/doc/man/manfr/man-html-0.9/man2/send.2.html
le paramètre passé au socket est de type void*. Donc au point de vue ormatage des données, tout dépend de la manière dont tu lis les données à la réception. Là, tu utilise un char, de seulement 9 cases, je suis étonner que tu n'es pas d'erreur de segmentation !
réfléchi encore là dessus à mon avis.
le paramètre passé au socket est de type void*. Donc au point de vue ormatage des données, tout dépend de la manière dont tu lis les données à la réception. Là, tu utilise un char, de seulement 9 cases, je suis étonner que tu n'es pas d'erreur de segmentation !
réfléchi encore là dessus à mon avis.
siskozed
Messages postés
69
Date d'inscription
mercredi 16 janvier 2008
Statut
Membre
Dernière intervention
2 septembre 2009
86
7 mai 2008 à 11:33
7 mai 2008 à 11:33
en fait, c'ets différent entre linux et RTOS, j'ai trouvé cette fonction dans la doc donc ca m'étonnerait que ce soit faux. Merci quand même,
;)
Leny
;)
Leny
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
7 mai 2008 à 11:46
7 mai 2008 à 11:46
Je maintiens !
que send() accepte un char* ou un void*, au final c'est identique vu que tu donnes la taille des données en bit.
par contre, ton tram[9] devrais te causer des soucis de mémoire !
le sprintf(trame, "%2i%2i%3i%2i%2i%2i%2i%3i" écris bien 2+2+3+2+2+2+2+3 = 18 caractères dans trame alors que tu n'en aloue que 9.
Test avec un printf("longeur de trame : %d\n",strlen(trame)+1); pour vérifier.
C'est quoi RTOS ?
que send() accepte un char* ou un void*, au final c'est identique vu que tu donnes la taille des données en bit.
par contre, ton tram[9] devrais te causer des soucis de mémoire !
le sprintf(trame, "%2i%2i%3i%2i%2i%2i%2i%3i" écris bien 2+2+3+2+2+2+2+3 = 18 caractères dans trame alors que tu n'en aloue que 9.
Test avec un printf("longeur de trame : %d\n",strlen(trame)+1); pour vérifier.
C'est quoi RTOS ?
siskozed
Messages postés
69
Date d'inscription
mercredi 16 janvier 2008
Statut
Membre
Dernière intervention
2 septembre 2009
86
7 mai 2008 à 14:04
7 mai 2008 à 14:04
RTOS C'est un OS Temps réel (REAL TIME OPERATING SYSTEM) distribué par BECK IPC sur leurs cartes. Moi j'utilise une carte SC13 avec DK51.
Pour ce qui est du probleme avec la trame, je n'ai pas rencontré ce problème, en fait j'arrive à visualiser toutes les informations enregistrées dedans... Mais c'est vrai que ca m'échappe...
J'ai un problème maintenant pour récupérer cette trame, je voulais faire un sscanf mais vu que je ne l'ai jamais utilisé encore, je ne suis pas sur de la synthaxe. Voilà ce que j'ai fait :
_________________
Les variables ne prennent pas les bonnes valeurs...
Pour ce qui est du probleme avec la trame, je n'ai pas rencontré ce problème, en fait j'arrive à visualiser toutes les informations enregistrées dedans... Mais c'est vrai que ca m'échappe...
J'ai un problème maintenant pour récupérer cette trame, je voulais faire un sscanf mais vu que je ne l'ai jamais utilisé encore, je ne suis pas sur de la synthaxe. Voilà ce que j'ai fait :
char *pBuf=new char[256]; int BufSize = 256; ... ... // reçoit la trame du serveur Receive(pBuf,BufSize); ... ... sscanf(pBuf, "%2%2%3%2%2%2%2%3", vrafvent1,vrafvent2,dvent,temp1, temp2,signe,hygr,pluv); ...
_________________
Les variables ne prennent pas les bonnes valeurs...
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
7 mai 2008 à 14:16
7 mai 2008 à 14:16
Si trame ne plante pas, c'est un coup de chance. Je ne sais pas exactement comment se comporte la gestion de la mémoire par l'exécutable, mais il en demande une certaine quantité qu'il alloue comme il veux.
Donc il arrive que dépasser un tableau ne cré pas de segfault car on écrit dans un espace mémoire allouer. MAIS ce n'est pas propre. Il se peut que suite à des modifications dans le programme aller lire en dehors du tableau devienne interdit. Il est aussi possible que lorsque tu va ainsi en dehors du tableau tu affectes une autre variable : erreurs garanties !
Il ne faut JAMAIS écrire en dehors de la place allouer à un tableau !
sinon, pour ton sscanf(), je ne l'ai jamais utilisé, mais déjà, tu peux faire de manière plus propre :
Ensuite, la fonction Receive(), je ne connait pas, en socket on utilise plutôt recv()
à mon avis, il faut préciser le type dans sscanf() %2i et non %2, http://pwet.fr/man/linux/fonctions_bibliotheques/scanf/
Comme ça tu fait la conversion directement de chaine de caractère à entier !
Donc il arrive que dépasser un tableau ne cré pas de segfault car on écrit dans un espace mémoire allouer. MAIS ce n'est pas propre. Il se peut que suite à des modifications dans le programme aller lire en dehors du tableau devienne interdit. Il est aussi possible que lorsque tu va ainsi en dehors du tableau tu affectes une autre variable : erreurs garanties !
Il ne faut JAMAIS écrire en dehors de la place allouer à un tableau !
sinon, pour ton sscanf(), je ne l'ai jamais utilisé, mais déjà, tu peux faire de manière plus propre :
int BufSize = 256; char *pBuf=new char[BufSize];Ainsi, si par hasard tu modifie BufSize tu modifiera la taille de pBuf en même temps.
Ensuite, la fonction Receive(), je ne connait pas, en socket on utilise plutôt recv()
à mon avis, il faut préciser le type dans sscanf() %2i et non %2, http://pwet.fr/man/linux/fonctions_bibliotheques/scanf/
Comme ça tu fait la conversion directement de chaine de caractère à entier !
siskozed
Messages postés
69
Date d'inscription
mercredi 16 janvier 2008
Statut
Membre
Dernière intervention
2 septembre 2009
86
7 mai 2008 à 16:42
7 mai 2008 à 16:42
exact ! merci pour tout ca char Snipeur, j'ai modifié et je me suis rendu compte de mon oubli des i dans %2 lol...
Pour ce qui est de Receive(), c'est une méthode de la classe CAsynchsocket dont ma classe hérite, donc c'est la synthaxe adéquat ici.
J'ai un peu avancé :
J'ai maintenant réussi à faire passer quelque chose dans les variables, cependant j'ai désormais un autre problème.
Voici ce que contient pBuf après " Receive(pBuf,BufSized); " :
- " 0 029925 5 030325"
Donc si vous avez suivis, la trame se décompose suivant ce mode opératoire :
2 entiers = vitesse des rafales de vents (dizaines et unités)
2 entiers = vitesse des rafales de vents (dizièmes)
3 entiers = direction du vent (centaines, dizaines, unités)
2 entiers = valeur absolue temperature exterieure (dizaine et unité)
2 entiers = valeur absolue temperature exterieure (dizièmes)
1 entier = signe de la temperature exterieure
2 entiers = hygrometrie exterieure (dizaine et unité)
3 entiers = pluviometrie (centaines, dizaines, unités)
OR
si je regarde ce que contient les variables grâce au debugger de visual, on voit :
vrafvent = 0,
vrafvent2 = 2,
dvent = 992,
temp = 5,
temp2 = 5,
signe = 2,
hygr = 43,
pluv = 25
Pour ce qui est de Receive(), c'est une méthode de la classe CAsynchsocket dont ma classe hérite, donc c'est la synthaxe adéquat ici.
J'ai un peu avancé :
int BufSize = 256; char *pBuf=new char[BufSize]; ... ... // reçoit la trame du serveur Receive(pBuf,BufSize); ... ... sscanf(pBuf, "%2i%2i%3i%2i%2i%2i%2i%3i", &vrafvent1,&vrafvent2,&dvent,&temp1, &temp2,&signe,&hygr,&pluv);
J'ai maintenant réussi à faire passer quelque chose dans les variables, cependant j'ai désormais un autre problème.
Voici ce que contient pBuf après " Receive(pBuf,BufSized); " :
- " 0 029925 5 030325"
Donc si vous avez suivis, la trame se décompose suivant ce mode opératoire :
// création de la trame sprintf(trame, "%2i%2i%3i%2i%2i%i%2i%3i", capteur_station.vrafvent , capteur_station.vrafvent2 , capteur_station.dvent , capteur_station.temp , capteur_station.temp2 , capteur_station.signe , capteur_station.hygr , capteur_station.pluv );
2 entiers = vitesse des rafales de vents (dizaines et unités)
2 entiers = vitesse des rafales de vents (dizièmes)
3 entiers = direction du vent (centaines, dizaines, unités)
2 entiers = valeur absolue temperature exterieure (dizaine et unité)
2 entiers = valeur absolue temperature exterieure (dizièmes)
1 entier = signe de la temperature exterieure
2 entiers = hygrometrie exterieure (dizaine et unité)
3 entiers = pluviometrie (centaines, dizaines, unités)
OR
si je regarde ce que contient les variables grâce au debugger de visual, on voit :
vrafvent = 0,
vrafvent2 = 2,
dvent = 992,
temp = 5,
temp2 = 5,
signe = 2,
hygr = 43,
pluv = 25
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
7 mai 2008 à 17:07
7 mai 2008 à 17:07
pff... c'est chiant ! je voi pas pourquoi ça merde comme ça. mis à par que dans le sprintf tu met %i à la place de %1i et que pour lire tu met %2i !
Sinon, au lieu de te faire chier, si tu fait le client aussi :
int trame = new int[9];
puis trame[0]=vrafvent, trame[2]=dvent; ...
puis tu envoie avec send() :
send(socket,(char*)trame,9*sizeof(int)...);
Dans le client tu recoit pareil :
Receive(pBuf,BufSized);
puis
int * trame;
trame=(int*)pBuf;
et tu récupères tram[0] à trame[8] par simple égalité :
vrafvent=trame[0]
...
moi en tout cas, je ferai un jolie cast comme ça, en vérifiant bien que les int ont la même taille sur le client et le serveur, sinon c'est un peu plus compliquer.
Sinon, au lieu de te faire chier, si tu fait le client aussi :
int trame = new int[9];
puis trame[0]=vrafvent, trame[2]=dvent; ...
puis tu envoie avec send() :
send(socket,(char*)trame,9*sizeof(int)...);
Dans le client tu recoit pareil :
Receive(pBuf,BufSized);
puis
int * trame;
trame=(int*)pBuf;
et tu récupères tram[0] à trame[8] par simple égalité :
vrafvent=trame[0]
...
moi en tout cas, je ferai un jolie cast comme ça, en vérifiant bien que les int ont la même taille sur le client et le serveur, sinon c'est un peu plus compliquer.
siskozed
Messages postés
69
Date d'inscription
mercredi 16 janvier 2008
Statut
Membre
Dernière intervention
2 septembre 2009
86
7 mai 2008 à 17:45
7 mai 2008 à 17:45
merci beaucoup je suis en train de faire quelques petits changements comme t'as dis. Je remettrais à jour le sujet ce soir, on verra ;)...
allez un peu de courage... après 8 heures de taf, on renchaine chez soit... dur dur d'être informaticien... lol
merci en tout cas !
allez un peu de courage... après 8 heures de taf, on renchaine chez soit... dur dur d'être informaticien... lol
merci en tout cas !
siskozed
Messages postés
69
Date d'inscription
mercredi 16 janvier 2008
Statut
Membre
Dernière intervention
2 septembre 2009
86
7 mai 2008 à 21:52
7 mai 2008 à 21:52
Bien joué !!!!
J'ai réussi !!!!!
Voilà ce que j'ai ajouté/modifié clairement (a peu pres la même chose que ce que tu disais "Char Snipeur") :
//////////////////////////////////////////////côté client (RTOS, C)
déclarations dans le .h
fonction dans le .c
//////////////////////////////////////////////côté serveur (Windows XP,MFC C++)
YES !!!!!!! Merci à tous et surtout à toi Char Snipeur :p
J'ai réussi !!!!!
Voilà ce que j'ai ajouté/modifié clairement (a peu pres la même chose que ce que tu disais "Char Snipeur") :
//////////////////////////////////////////////côté client (RTOS, C)
déclarations dans le .h
char trame[5];
fonction dans le .c
trame[0] = capteur_station.vrafvent + capteur_station.vrafvent2/10 ; trame[1] = capteur_station.dvent ; switch(capteur_station.signe) { case 0: trame[2] = capteur_station.temp + capteur_station.temp2/10; break; case 1: trame[2] = -capteur_station.temp - capteur_station.temp2/10; break; }; trame[3] = capteur_station.hygr ; trame[4] = capteur_station.pluv ;
//////////////////////////////////////////////côté serveur (Windows XP,MFC C++)
int CMeteo::Run() { int BufSize = 256; char *pBuf=new char[BufSize]; m_IPSrv = "192.168.1.56"; m_Port = 4000; int vrafvent1=0; int vrafvent2=0; float vrafvent=0; int dvent=0; int temp1=0; int temp2=0; float temp=0; int signe=0; int hygr=0; int pluv=0; //m_pCommSocket->setDoc(m_pDonnees); // transfert de l'adresse du pointeur m_pDonnees à la classe CCommSocket // client,cree un socket par default m_pCommSocket.Create(); // ouvre la connexion sur le serveur m_pCommSocket.Connect(m_IPSrv,m_Port); // reçoit la trame du serveur m_pCommSocket.Receive(pBuf,BufSize); // ferme le socket connecte Sleep(1); m_pCommSocket.Close(); Sleep(1); vrafvent = pBuf[0]; dvent = pBuf[1]; temp = pBuf[2]; hygr = pBuf[3]; pluv = pBuf[4]; Sleep(1); m_pDonnees->m_pVerrouMeteo.Lock(); // simple verrou m_pDonnees->acquisitionReelleMeteo[0]= temp; // acquisitionReelleMeteo[] est le tableau m_pDonnees->acquisitionReelleMeteo[1]= (float)hygr; // qui sert à afficher dans l'IHM. m_pDonnees->acquisitionReelleMeteo[2]= (float)pluv; // On y accède par le pointeur m_pDonnees->acquisitionReelleMeteo[3]= vrafvent; // m_pDonnees declare avant comme ceci m_pDonnees->acquisitionReelleMeteo[4]= (float)dvent; // CNomdeProjetDoc * m_pDonnees; m_pDonnees->m_pVerrouMeteo.Unlock(); delete[]pBuf; return (0); }
YES !!!!!!! Merci à tous et surtout à toi Char Snipeur :p
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
9 mai 2008 à 08:01
9 mai 2008 à 08:01
Salut.
Si ça fonctionne tant mieux !
MAIS, si je t'avais conseiller d'utiliser les int à la place des char, c'est pour une bonne raison.
J'ai remarqué que la valeur de dvent prenait comme valeur 992. Or le type char est en général limité à 256 valeurs possibles (de -128 à127 ou de 0 à 256), le type char ne permet pas alors de représenter la valeur 992, d'où le transtypage proposé. (sinon, d'après les aures valeur, je t'aurai conseillé ce que tu as fait).
Si ça fonctionne tant mieux !
MAIS, si je t'avais conseiller d'utiliser les int à la place des char, c'est pour une bonne raison.
J'ai remarqué que la valeur de dvent prenait comme valeur 992. Or le type char est en général limité à 256 valeurs possibles (de -128 à127 ou de 0 à 256), le type char ne permet pas alors de représenter la valeur 992, d'où le transtypage proposé. (sinon, d'après les aures valeur, je t'aurai conseillé ce que tu as fait).