2010-04-25 6 views
10

Je sais que vous ne devriez pas mélanger l'impression avec printf, cout et wprintf, wcout, mais avez du mal à trouver une bonne réponse et pourquoi il est possible de contourner. Le problème est que j'utilise une bibliothèque externe qui imprime avec printf et la mienne utilise wcout. Si je fais un exemple simple, cela fonctionne très bien, mais de mon application complète, il n'imprime simplement pas les instructions printf. Si c'est vraiment une limitation, alors il y aurait beaucoup de bibliothèques qui ne peuvent pas travailler ensemble avec de larges applications d'impression. Toute idée à ce sujet est plus que bienvenue.C++ Mélanger printf avec wprintf (ou cout avec wcout)

Mise à jour:

Je fait bouillir jusqu'à:

#include <stdio.h> 
#include <stdlib.h> 
#include <iostream> 

#include <readline/readline.h> 
#include <readline/history.h> 

int main() 
{ 
    char *buf; 

    std::wcout << std::endl; /* ADDING THIS LINE MAKES PRINTF VANISH!!! */ 

    rl_bind_key('\t',rl_abort);//disable auto-complete 

    while((buf = readline("my-command : "))!=NULL) 
    { 
     if (strcmp(buf,"quit")==0) 
      break; 

     std::wcout<<buf<< std::endl; 

     if (buf[0]!=0) 
      add_history(buf); 
    } 

    free(buf); 

    return 0; 
} 

Je pense que oui, il pourrait être un problème de rinçage, mais il semble encore étrange pour moi, je dois vérifier sur le sujet.

Mise à jour -> Contournez:

Tout d'abord, le même problème se pose avec wprintf. Mais je trouve que l'ajout:

std::ios::sync_with_stdio(false); 

a effectivement fait l'affaire ... (fausse note et non pas comme j'attendre vrai ..), la seule chose qui me dérange, que je ne comprends pas pourquoi et comment le comprendre :-(

+0

je fait bouillir à ce qui suit: #include #include #include \t #include #include int main ( { char * buf; std :: wcout << std :: endl;/* AJOUT DE CETTE LIGNE FAIT PRINTF VANISH !!! */ rl_bind_key ('\' t, rl_abort); // désactiver tandis que l'auto-complétion ((buf = readline ("my-commande:"!)) = NULL) { if (strcmp (BUF, "quitter") == 0) pause; std :: wcout << buf << std :: endl; Si (buf [0]! = 0) add_history } libre (buf); return 0; } –

+0

désolé mon erreur de toute évidence ne pas être utilisé avec des extraits de code. –

+1

Pourquoi les réponses se concentrent sur le mélange de 'cout' et' printf', alors que la question est de mélanger 'cout' et' wcout' ... – kennytm

Répondre

6

Vous devriez être en mesure de les mélanger, mais ils utilisent généralement des mécanismes de mise en mémoire tampon séparés afin qu'ils se chevauchent:

printf("hello world"); 
cout << "this is a suprise"; 

peut entraîner:

hellothis est un monde suprise

Vous ne fournissez pas suffisamment d'informations pour diagnostiquer votre problème avec printf() dans votre application, mais je suppose que vous avez plus d'un runtime c (un dans votre code, un en le code printf()) et il y a un conflit.

+0

Ce que je fais utilise la bibliothèque GNL readline pour l'histoire de la ligne de commande. Donc, mon application est liée à cette bibliothèque. –

+1

Je pourrais ajouter, que si nous parlons de mélanger cout et wcout (et non printf et wcout), alors c'est mon expérience, il n'est pas seulement brouillé c'est un problème, l'application peut tomber en panne. Merci pour votre réponse. –

+0

@Bo Jensen: Ce n'est pas la faute de wcout. C'est ta faute. Soit cela ou il y a un bug dans votre implémentation de la bibliothèque standard C++. –

5

Je pense que vous parlez de std::ios_base::sync_with_stdio, mais IIRC est activé par défaut.

2

Les tampons printf() et cout sont synchronisés par défaut ou sont en fait le même tampon. Si vous rencontrez des problèmes avec mise en mémoire tampon, la solution évidente consiste à vider le tampon après chaque sortie:

fflush(stdout); 
cout.flush(); 

ce vide le tampon (s) du système d'exploitation, et une fois fait, il n'y a aucune possibilité de désentrelacement, ou de sortie étant perdue.

0

maux de tête de mise en mémoire tampon. généralement, vous pouvez, cependant, car ils sont synchronisés. Les gens qui vous disent de ne pas le faire sont probablement des gens qui se souviennent de la douleur de l'utilisation de plusieurs méthodes et veulent vous en sauver. (ne pas mélanger avec les appels système, ce serait douloureux.)

0

Les bibliothèques ne doivent pas utiliser printf, cout ou toute autre E/S sur des poignées standard. Ils doivent utiliser une routine de rappel pour déléguer la sortie à une méthode du choix du programme principal.

Une exception évidente est une bibliothèque dont le seul but est la sortie, mais c'est le choix du programme principal pour l'utiliser.Et cette règle n'interdit pas aux E/S de déposer des descripteurs ouverts par la bibliothèque.

Non seulement cela résoudrait le problème soulevé ici, mais il prend également en charge le fonctionnement déconnecté (programme linux sans tty, par exemple exécuté via nohup, ou service Win32).