IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Créer un flux de floats


Sujet :

C++

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    117
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 117
    Par défaut Créer un flux de floats
    Salut !

    J'ai un peu regardé la faq concernant les flots ...

    Je voudrais envoyer un tableau de floats (générés aléatoirement) par socket, en envoyant d'abord le tableau dans un flux puis envoyer ce flux par socket ...
    La seule chose que je trouve est de transformer le nombre en binaire ou en hexa pour l'envoyer puis de faire la conversion à la récupération du flux.

    Je me demandais s'il n'était pas possible de directement écrire les floats dans le flux en tant que binaire (écrire automatiquement les bits) plutôt que de passer par une string ou un caractère serait 0 ou 1 dans mon cas.

    En gros je voudrais pouvoir faire comme pour la lecture dans un fichier en binaire ...

    Quelqu'un aurait une solution ?

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 90
    Par défaut
    en envoyant d'abord le tableau dans un flux puis envoyer ce flux par socket
    Pourquoi vouloir passer par un flux ? C'est trop simple d'utiliser directement le tableau ?

    Mais bon, si tu veux créer un istream qui sorte des float non formatés, voilà quelques pistes :
    • la lecture de données binaires depuis un stream se fait avec des méthodes du type read()
    • pour utiliser l'opérateur >> il va falloir le surcharger
    • 'last but not least', comment créer un istream à partir d'un tableau ? La seule solution que je connaisse est dériver stringbuf en Stringbuf (par exemple ; on peut aussi dériver basic_streambuf mais c'est plus compliqué) pour initialiser le tampon avec le tableau, puis initialiser un istream avec Stringbuf. J'ai proposé le code dans ce forum, mais je trouve que ce n'est pas très pratique. Si quelqu'un a mieux...

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 90
    Par défaut
    Si quelqu'un a mieux...
    J'ai mieux :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     vector<float> v;
     
     /* ... */ // initialisation de v
     
     stringbuf sb(ios_base::in | ios_base::out | ios_base::binary);
     iostream io(&sb);
     io.write((char *)&v[0],v.size()*sizeof(float));
     
     // le flux io est prêt pour la lecture avec read()

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    117
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 117
    Par défaut
    Ben je veux bien envoyer le tableau directement mais tu fais comment ? Ou alors dans ce cas tu transforme ton tableau en une chaine de caractères ...

    Ce que je voudrais moi c'est l'envoyer en binaire ...

    Boromir73 : Je suppose que ton code marche aussi avec un tableau au lieu d'un vector en faisant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    float tab[SIZE];
     
     /* ... */ // initialisation de tab
     
     stringbuf sb(ios_base::in | ios_base::out | ios_base::binary);
     iostream io(&sb);
     io.write((char *)&tab[0],SIZE*sizeof(float));

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 90
    Par défaut
    Je ne saisis pas bien ce que tu veux dire par "envoyer en binaire" :
    1 float (32bits) => 4 octets ?
    1 float (32bits) => 32 octets ?

    Quelle syntaxe utilises-tu pour l'instant avec ton socket ?

    Et oui, le code que je propose devrait marcher avec un tableau (mais ça fait 1 float (32bits) => 4 octets).

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    117
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 117
    Par défaut
    Oui c'est envoyer 4 octexct que je veux.

    En gros je veux lire un float en lisant un bloc de taille sizeof(float)

    Mai sje ne veux pas lire une séquence de 1 et de 0 à la main ...

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 90
    Par défaut
    Ok.
    Quelle syntaxe utilises-tu pour l'instant avec ton socket ?

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    117
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 117
    Par défaut
    Pour le moment pour envoyer mes données je fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    std::ostringstream oss;
    for(int i=0; i < nbChannels; i++){
    	oss << (float)(-15 + ((double)rand() / ((double)RAND_MAX + 1) * 30)) << ";";
    }
    oss << std::endl;
    std::string result = oss.str();
    send(AcquisitionServeur::acceptation, result.c_str(), result.size(), 0);
    Et pour les lire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    int lire = recv(sock, tampon, sizeof(tampon), 0);
    	if(lire != SOCKET_ERROR){
    		for(int i =0; i < lire; ++i){
    			if(tampon[i] == ';'){
    				sampleList.push_back((float)atof(tmp));
    				if (sampleList.size() == nbCol){
    					sendValuedEvent(_destination, eeg_eventId, sampleList);
    					sampleList.clear();
    				}
    				for(k=0; k<256; k++) tmp[k] = '\0'; 
    				k = 0;
    			} else {
    				tmp[k++] = tampon[i];
    			}
    		}
    	}
    }
    En gros je parse mùa chaine d'arrivée ...

    par contre je vois bien ce que tu veux dire pour écrire en binaire dans le flot, mais tu le passe comment le flot après au socket ?

    Tu fais comme ça ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    stringbuf sb(ios_base::in | ios_base::out | ios_base::binary);
    iostream io(&sb);
    float t;
    for(int i=0; i < nbChannels; i++){
    	t = -15 + ((double)rand() / ((double)RAND_MAX + 1) * 30);
    	io.write((char *)&t,sizeof(float));
    }
    send(AcquisitionServeur::acceptation,io , nbChannels*sizeof(float), 0);

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    117
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 117
    Par défaut
    Et pour savoir tu inclu quel header pour pouvoir utiliser les ios_base ?

  10. #10
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 90
    Par défaut
    Pour écrire dans ton socket (mais sans les ';') :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
     vector<float> v;
     
     /* initialisation de v */
     
     send(AcquisitionServeur::acceptation, (char *)&v[0], v.size()*sizeof(float), 0);
    Pour écrire dans ton socket (avec les ';') :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
     ostringstream oss;
     
     /* remplissage de oss (en utilisant write pour les floats) */
     
     string result(oss.str());
     send(AcquisitionServeur::acceptation, result.c_str(), result.size(), 0);
    quel header pour pouvoir utiliser les ios_base
    #include <ios>

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    117
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 117
    Par défaut
    Ok onm'a expliqué un truc que j'avais pas compris sur les sockets ...

    Quan j'écrivais ma chaine je n'avais pas fait le lien avec le fait que j'écris à partir d'une adresse et sur une taille donnée ...

    Donc en écrivant directement les floats (à partir de leur adresse) sur leur taille dans le socket ça fera excatement ce que je veux ...

    je sais je suis un boulet

  12. #12
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    117
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 117
    Par défaut
    Du coup voilà mon code pour envoyer, il semble bon ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    for(int i=0; i < nbChannels; i++){
    	tab[i] = (float)(-15 + ((double)rand() / ((double)RAND_MAX + 1) * 30));
    }
    send(AcquisitionServeur::acceptation, (char*)&tab, nbChannels*sizeof(float), 0);
    Par contre à la réception j'ai un pb ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    float* tampon = new float[nbCol];
    int lire = recv(sock, (char*)tampon, sizeof(float)*nbCol, 0);
    if(lire != SOCKET_ERROR){
    	/* lecture du tableau */
    }
    et là il trouve des résultats incohérents dans le tableau ...

    Le client et le serveur s'exécute pour le moment sur la même machine, mais comment passer les données par un mode réseau (comme htons htonl pour les int) avec des floats.

    J'ai entendu parler de XDR et RPM il me semble ...

  13. #13
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 90
    Par défaut
    Ce n'est pas "(char *)&tab" mais "(char *)tab".

  14. #14
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    117
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 117
    Par défaut
    En effet merci !

    Ca à l'air mieux d'un coup

    Faut que je vérifie plus en détail maintenant

  15. #15
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    T'es au courant que c'est pas portable du tout j'espère ?

  16. #16
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    117
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 117
    Par défaut
    Le côté envoi de données ça m'importe peu ça utilise une machine d'acquisition dont le driver n'a été fait pou windows ...

    Par contre je ne vois pas pourquoi le code ne serait pas portable pour la récupération des données (au #ifdef près en fonction de si on est sous windows ou sous linux ...)

    Donc a part les sockets je ne vois pas ce qui ne serait pas portable (et encore les sockets ça m'a demandé un copier cooler sur le net pour le rendre portable)

  17. #17
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    je ne vois pas pourquoi le code ne serait pas portable pour la récupération des données
    Tout simplement parce toutes les machines n'utilisent pas la même représentation binaire des nombres flottants.

  18. #18
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    117
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 117
    Par défaut
    Ah oui ça aussi ...

    C'est pour ça que je demandais s'il y avait l'équivalent des htons/l pour les flottants ...

  19. #19
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    C'est pire que ça. Je ne suis même pas sûr que toutes les machines utilisent la même convention IEEE pour les flottants -- on n'a déjà pas de garantie de taille...
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Créer un flux RSS
    Par okoweb dans le forum Langage
    Réponses: 16
    Dernier message: 26/10/2011, 12h55
  2. Créer un flux XML dans un dataHandler
    Par flethiel dans le forum Format d'échange (XML, JSON...)
    Réponses: 1
    Dernier message: 25/09/2007, 12h03
  3. [FLASH MX2004] Créer un flux xml
    Par j0hnmerrick dans le forum Flash
    Réponses: 3
    Dernier message: 23/02/2005, 12h02
  4. [DOM] Comment créer des flux XML en java ?
    Par nean_j dans le forum Format d'échange (XML, JSON...)
    Réponses: 3
    Dernier message: 27/04/2004, 12h00

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo