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 :

Lire cin "au vol"


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Septembre 2007
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 28
    Par défaut Lire cin "au vol"
    Bonjour !

    Je programme un exe qui utilise CIN / COUT pour communiquer avec la console, j'aimerais pouvoir lui donner des ordre, mais sans bloquer l’exécution.

    Comment faire pour récupérer le contenu de std::cin, ou rien s'il est vide ?

    J'ai essayé de faire :

    nb = std::cin.readsome(&C[0], nbAtt);

    avec nbAtt = 1

    mais ça ne récupère rien, pourtant le buffer se remplis bien puisqu'il s'affiche dans la ligne de commande une fois l'exe terminé !

    Des conseils, des explications ?...

    Merci d'avance !

    Précision : c'est en C++ avec Visual Studio Express 2012

  2. #2
    Membre Expert Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 048
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 048
    Par défaut
    Bonjour,

    Un peu de recherche sur le FAQ ou sur google te donne la réponse en 2 secondes

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::string nb;
    getline(cin, nb);
    NB: j'ai loupé le coup du "Non bloquant", une seule façon... un thread

  3. #3
    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
    Il faut aller attaquer la console de ton système (via l'API qui va bien -- et non je ne la connais pas) pour permettre de tester la présence de caractères. Soit, pour passer cin en non bloquant.
    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...

  4. #4
    Membre averti
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Septembre 2007
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 28
    Par défaut
    Citation Envoyé par Astraya Voir le message
    Bonjour,

    Un peu de recherche sur le FAQ ou sur google te donne la réponse en 2 secondes

    NB: j'ai loupé le coup du "Non bloquant", une seule façon... un thread
    Tsss, sur que j'ai demandé à Google avant !

    Une meilleur lecture de la question te permet de ne pas répondre pour rien !

    Oui, un thread... mais je n'ai pas trouvé comment faire, il semble qu'il faut pour cela que je passe en version complète...

    C'était ce que je voulais faire au départ, d'autant qu'il est probable que je mette d'autres traitements dans mon exe, je vais aller en causer avec Google... (et avec mon boss pour qu'il m'offre la version pro)

    Merci quand même !

  5. #5
    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
    Un thread ne sert à rien là. (à part jouer avec des sémaphores ou autres trucs dans le genre: la partie qui lit sur cin se bloque et on continue à faire d'autres choses ailleurs -- à ce propos je ne vois pas le rapport avec "version payante")

    Non, il faut dire à la console que l'on peut mettre des choses dans le buffer de cin sans devoir attendre l'appui sur "entrée".
    Au pire, tu as PDCurses, mais bon.
    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...

  6. #6
    Membre averti
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Septembre 2007
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 28
    Par défaut
    Citation Envoyé par Luc Hermitte Voir le message
    Un thread ne sert à rien là. (à part jouer avec des sémaphores ou autres trucs dans le genre: la partie qui lit sur cin se bloque et on continue à faire d'autres choses ailleurs -- à ce propos je ne vois pas le rapport avec "version payante")
    D'après ce que j'avais vu, les bibliothèques qui permettre de faire du multi thread ne sont pas intégrées dans la version "Express"...

    J'en aurais besoin pour intégrer d'autres traitements à mon appli, mais pour l'instant elle n'a qu'une tache en charge alors il n'y a pas urgence.

    Citation Envoyé par Luc Hermitte Voir le message
    Non, il faut dire à la console que l'on peut mettre des choses dans le buffer de cin sans devoir attendre l'appui sur "entrée".
    Au pire, tu as PDCurses, mais bon.
    Hum... réflexion inintéressante... Je vais creuser...

    C'est pour une appli sous Flex (Flash Builder) et l'exe est lancé dans un NativeProcess qui communique avec Flex via les stdin/out et err.

    Déjà j'ai été obligé d'ajouter des Flush() car Flex ne reçoit les données qu'une fois le buffer vidé (alors que le terminal affiche en temps réel), c'est donc le même genre de question, s'il existe un flush dans l'autre sens, peut être que ma lecture fonctionnera !

    A suivre...

  7. #7
    Membre actif
    Homme Profil pro
    Ingénieur
    Inscrit en
    Octobre 2006
    Messages
    48
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Transports

    Informations forums :
    Inscription : Octobre 2006
    Messages : 48
    Par défaut
    Bonjour,

    C'est toujours assez frustrant de se rendre compte qu'en C++ on n'a pas nécessairement ce qu'il faut en standard pour résoudre des problèmes simples.

    La nouvelle norme du C++11 apporte un support des threads et de la programmation concurrente mais en ce qui concerne les I/O asynchrones rien de nouveau.

    Quand iostream a été pensé, il n'y avait pas de thread en standard. Toutes les interfaces du standard sont donc bloquantes. Je ne connais aucun moyen de changer ce comportement.

    Si l'on veut rester au plus près du standard (avec un compilateur supportant le C++11) on peut s'en sortir avec quelque chose comme ça :
    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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    #include <iostream>
    #include <future>
    #include <chrono>
    #include <tuple>
    #include <type_traits>
    #include <string>
     
    namespace tupleit {
    	// utilitaires pour la manipulation de tuple
    	template<std::size_t I = 0, typename FuncT, typename... Tp>
    	inline typename std::enable_if<I == sizeof...(Tp), void>::type
    	for_each(std::tuple<Tp...>&, FuncT)
    	{ }
     
    	template<std::size_t I = 0, typename FuncT, typename... Tp>
    	inline typename std::enable_if < I <sizeof...(Tp), void>::type
    	for_each(std::tuple<Tp...>& t, FuncT f)
    	{
    		f(std::get<I>(t));
    		for_each < I + 1 > (t, f);
    	}
    }
     
    struct Cin 
    {
    	template <typename T>
    	void operator()(T& t) {
    		std::cin >> t;
    	}
    };
     
    template <typename... Args>
    class asyncin {
    	std::future<void> ftr;
    	std::tuple<Args...> ret;
    public:
    	asyncin() : ftr(std::async(std::launch::async, [this]() {
                tupleit::for_each(ret, Cin());
    	}))
    	{}
     
    	template< class Rep, class Period >
    	std::future_status  wait_for(const std::chrono::duration<Rep,Period>& timeout_duration) const {
    		return ftr.wait_for(timeout_duration);
    	}
     
    	// fonction bloquante
    	void get(Args&... args) const {
    		ftr.wait();
    		std::tie(args...) = ret; // todo : copy -> move
    	}
     
    };
     
    int main()
    {
    	// entree asynchrone de myint et mystr
    	int myint{};
    	std::string mystr{};
    	asyncin<int, std::string> acin{};
     
    	// ... pendant un traitement quelconque ...
    	for(auto i : {1, 2, 3, 4, 5, 6, 7 ,8 ,9}) {
    		std::cout << i;
    		std::this_thread::sleep_for(std::chrono::seconds(1));
    	}
     
    	// On attend myint et mystr
    	if(std::future_status::ready == acin.wait_for(std::chrono::seconds(1))) {
    		if(std::cin.good()) {
    			acin.get(myint, mystr);
    			std::cout << std::endl << "(Myint, Mystr) = (" << myint << ", " << mystr << ")";
    		} 
    		else {
    			std::cout << std::endl << "Bad input" << std::endl;
    			std::cin.clear();
    		}
    	}
    	else {
    		std::cout << "Timeout ! " << std::endl;
    		// On ne peut pas annuler l'operation asynchrone en std C++11 (tuer le thread)
    		// On a le choix :
    		//  - reboucler et attendre indefiniment le thread 
    		// OU
    		//  - recuperer std::thread::native_handle et tuer le thread avec l'API native 
    		//	  dans le destructeur de asyncin par exemple qui se chargerait de nettoyer egalement le buffer de cin.
    	}
        return 0;
    }
    Ca reste relativement simple, c'est juste dommage qu'il n'y ait pas d'équivalent dans le standard ...

Discussions similaires

  1. Quote et double quote
    Par aktos dans le forum Langage
    Réponses: 8
    Dernier message: 05/01/2007, 19h55

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